2023-03-12 16:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GoToSocial  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Copyright (C) GoToSocial Authors admin@gotosocial.org  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SPDX-License-Identifier: AGPL-3.0-or-later  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.  
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  dereferencing  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"cmp" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/activity/pub" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/ap" 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/config" 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/db" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtscontext" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtserror" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/id" 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 09:47:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/log" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-09 18:41:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/media" 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 12:38:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/util" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// accountFresh returns true if the given account is  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// still considered "fresh" according to the desired  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// freshness window (falls back to default if nil).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Local accounts will always be considered fresh because  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// there's no remote state that could have changed.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// True is also returned for suspended accounts, since  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// we'll never want to try to refresh one of these.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Return value of false indicates that the account  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is not fresh and should be refreshed from remote.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  accountFresh (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									window  * FreshnessWindow , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  window  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										window  =  DefaultAccountFreshness 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-10 17:16:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . IsLocal ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Can't refresh 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// local accounts. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 15:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . IsSuspended ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Can't/won't refresh 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// suspended accounts. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . IsInstance ( )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										! account . IsNew ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Existing instance account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// No need for refresh. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Moment when the account is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// considered stale according to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// desired freshness window. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									staleAt  :=  account . FetchedAt . Add ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										time . Duration ( * window ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It's still fresh if the time now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is not past the point of staleness. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! time . Now ( ) . After ( staleAt ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-23 10:58:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetAccountByURI will attempt to fetch an accounts by its URI, first checking the database. In the case of a newly-met remote model, or a remote model  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority account information  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  GetAccountByURI ( ctx  context . Context ,  requestUser  string ,  uri  * url . URL )  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch and dereference account if necessary. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									account ,  accountable ,  err  :=  d . getAccountByURI ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uri , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This account was updated, enqueue re-dereference featured posts + stats. 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:50:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . state . Workers . Dereference . Queue . Push ( func ( ctx  context . Context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountFeatured ( ctx ,  requestUser ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account featured collection: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountStats ( ctx ,  requestUser ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account stats: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  account ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// getAccountByURI is a package internal form of .GetAccountByURI() that doesn't bother dereferencing featured posts on update.  
						 
					
						
							
								
									
										
										
										
											2023-10-23 10:58:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  getAccountByURI ( ctx  context . Context ,  requestUser  string ,  uri  * url . URL )  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account  * gtsmodel . Account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uriStr   =  uri . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err      error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 10:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Search the database for existing account with URI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account ,  err  =  d . state . DB . GetAccountByURI ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// request a barebones object, it may be in the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// db but with related models not yet dereferenced. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gtscontext . SetBarebones ( ctx ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uriStr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "error checking database for account %s by uri: %w" ,  uriStr ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 10:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Else, search the database for existing by URL. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account ,  err  =  d . state . DB . GetAccountByURL ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gtscontext . SetBarebones ( ctx ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uriStr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( "error checking database for account %s by url: %w" ,  uriStr ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 10:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Ensure that this is isn't a search for a local account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  uri . Host  ==  config . GetHost ( )  ||  uri . Host  ==  config . GetAccountDomain ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err )  // this will be db.ErrNoEntries 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Create and pass-through a new bare-bones model for dereferencing. 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										account ,  accountable ,  err  :=  d . enrichAccountSafely ( ctx ,  requestUser ,  uri ,  & gtsmodel . Account { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ID :      id . NewULID ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Domain :  uri . Host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											URI :     uriStr , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We have a new account. Ensure basic account stats populated; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// real stats will be fetched from remote asynchronously. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . StubAccountStats ( ctx ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( "error stubbing account stats: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  account ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountFresh ( account ,  nil )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This is an existing account that is up-to-date, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// before returning ensure it is fully populated. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . PopulateAccount ( ctx ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error populating existing account: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  account ,  nil ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Try to update existing account model. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latest ,  accountable ,  err  :=  d . enrichAccountSafely ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uri , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 12:02:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "error enriching remote account: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fallback to existing. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  account ,  nil ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  latest ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-23 10:58:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetAccountByUsernameDomain will attempt to fetch an accounts by its username@domain, first checking the database. In the case of a newly-met remote model,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// or a remote model whose last_fetched date is beyond a certain interval, the account will be dereferenced. In the case of dereferencing, some low-priority  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// account information may be enqueued for asynchronous fetching, e.g. featured account statuses (pins). An ActivityPub object indicates the account was dereferenced.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  GetAccountByUsernameDomain ( ctx  context . Context ,  requestUser  string ,  username  string ,  domain  string )  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									account ,  accountable ,  err  :=  d . getAccountByUsernameDomain ( 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 12:05:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										domain , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This account was updated, enqueue re-dereference featured posts + stats. 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:50:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . state . Workers . Dereference . Queue . Push ( func ( ctx  context . Context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 12:05:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountFeatured ( ctx ,  requestUser ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account featured collection: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountStats ( ctx ,  requestUser ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account stats: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 12:05:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  account ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 12:05:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getAccountByUsernameDomain is a package internal form of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetAccountByUsernameDomain() that doesn't bother deref of featured posts.  
						 
					
						
							
								
									
										
										
										
											2023-10-31 12:05:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  getAccountByUsernameDomain (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									username  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									domain  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  domain  ==  config . GetHost ( )  ||  domain  ==  config . GetAccountDomain ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We do local lookups using an empty domain, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// else it will fail the db search below. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										domain  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 10:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Search the database for existing account with USERNAME@DOMAIN. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									account ,  err  :=  d . state . DB . GetAccountByUsernameDomain ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// request a barebones object, it may be in the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// db but with related models not yet dereferenced. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gtscontext . SetBarebones ( ctx ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										username ,  domain , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "error checking database for account %s@%s: %w" ,  username ,  domain ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  domain  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// failed local lookup, will be db.ErrNoEntries. 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Create and pass-through a new bare-bones model for dereferencing. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										account ,  accountable ,  err  :=  d . enrichAccountSafely ( ctx ,  requestUser ,  nil ,  & gtsmodel . Account { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ID :        id . NewULID ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Domain :    domain , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Username :  username , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// We have a new account. Ensure basic account stats populated; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// real stats will be fetched from remote asynchronously. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . StubAccountStats ( ctx ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( "error stubbing account stats: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  account ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Try to update existing account model. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latest ,  accountable ,  err  :=  d . RefreshAccount ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nil , 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nil , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Fallback to existing. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  account ,  nil ,  nil  //nolint 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This is existing up-to-date account, ensure it is populated. 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . PopulateAccount ( ctx ,  latest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 09:39:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error populating existing account: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  latest ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RefreshAccount updates the given account if it's a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// remote account, and considered stale / not fresh  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// based on Account.FetchedAt and desired freshness.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// An updated account model is returned, but in the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// case of dereferencing, some low-priority account  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// info may be enqueued for asynchronous fetching,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// e.g. featured account statuses (pins).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// An ActivityPub object indicates the account was  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// dereferenced (i.e. updated).  
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  RefreshAccount (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accountable  ap . Accountable , 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									window  * FreshnessWindow , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If no incoming data is provided, 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check whether account needs refresh. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  ==  nil  && 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountFresh ( account ,  window )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  account ,  nil ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parse the URI from account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uri ,  err  :=  url . Parse ( account . URI ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "invalid account uri %q: %w" ,  account . URI ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Try to update + deref passed account model. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latest ,  accountable ,  err  :=  d . enrichAccountSafely ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uri , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountable , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "error enriching remote account: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "%w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 12:16:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This account was updated, enqueue re-dereference featured posts + stats. 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:50:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . state . Workers . Dereference . Queue . Push ( func ( ctx  context . Context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountFeatured ( ctx ,  requestUser ,  latest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account featured collection: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountStats ( ctx ,  requestUser ,  latest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account stats: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  latest ,  accountable ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RefreshAccountAsync enqueues the given account for  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// an asychronous update fetching, if it's a remote  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// account, and considered stale / not fresh based on  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Account.FetchedAt and desired freshness.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This is a more optimized form of manually enqueueing  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// .UpdateAccount() to the federation worker, since it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// only enqueues update if necessary.  
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  RefreshAccountAsync (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accountable  ap . Accountable , 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									window  * FreshnessWindow , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If no incoming data is provided, 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check whether account needs refresh. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountable  ==  nil  && 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 15:24:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountFresh ( account ,  window )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-29 10:24:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parse the URI from account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uri ,  err  :=  url . Parse ( account . URI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "invalid account uri %q: %v" ,  account . URI ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Enqueue a worker function to enrich this account async. 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 13:50:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d . state . Workers . Dereference . Queue . Push ( func ( ctx  context . Context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										latest ,  accountable ,  err  :=  d . enrichAccountSafely ( ctx ,  requestUser ,  uri ,  account ,  accountable ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error enriching remote account: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  accountable  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// This account was updated, enqueue re-dereference featured posts + stats. 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-14 15:57:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountFeatured ( ctx ,  requestUser ,  latest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account featured collection: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-11 11:54:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  d . dereferenceAccountStats ( ctx ,  requestUser ,  latest ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error fetching account stats: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// enrichAccountSafely wraps enrichAccount() to perform  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it within the State{}.FedLocks mutexmap, which protects  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// dereferencing actions with per-URI mutex locks.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  enrichAccountSafely (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uri  * url . URL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									accountable  ap . Accountable , 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2024-03-12 15:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Noop if account suspended; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we don't want to deref it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  account . IsSuspended ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-10 17:16:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  account ,  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// By default use account.URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// as the per-URI deref lock. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  uriStr  string 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . URI  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uriStr  =  account . URI 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// No URI is set yet, instead generate a faux-one from user+domain. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uriStr  =  "https://"  +  account . Domain  +  "/users/"  +  account . Username 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Acquire per-URI deref lock, wraping unlock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to safely defer in case of panic, while still 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// performing more granular unlocks when needed. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unlock  :=  d . state . FedLocks . Lock ( uriStr ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 12:38:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unlock  =  util . DoOnce ( unlock ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Perform status enrichment with passed vars. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latest ,  apubAcc ,  err  :=  d . enrichAccount ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uri , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account , 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-09 09:42:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountable , 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  gtserror . StatusCode ( err )  >=  400  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  account . IsNew ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This was a new account enrich 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// attempt which failed before we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// got to store it, so we can't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// return anything useful. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We had this account stored already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// before this enrichment attempt. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Update fetched_at to slow re-attempts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// but don't return early. We can still 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// return the model we had stored already. 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										account . FetchedAt  =  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . UpdateAccount ( ctx ,  account ,  "fetched_at" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Error ( ctx ,  "error updating %s fetched_at: %v" ,  uriStr ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Unlock now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we're done. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  errors . Is ( err ,  db . ErrAlreadyExists )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Ensure AP model isn't set, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// otherwise this indicates WE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// enriched the account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apubAcc  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// DATA RACE! We likely lost out to another goroutine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// in a call to db.Put(Account). Look again in DB by URI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latest ,  err  =  d . state . DB . GetAccountByURI ( ctx ,  account . URI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  gtserror . Newf ( "error getting account %s from database after race: %w" ,  uriStr ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 11:12:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  latest ,  apubAcc ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// enrichAccount will enrich the given account, whether a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// new barebones model, or existing model from the database.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It handles necessary dereferencing, webfingering etc.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  enrichAccount (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uri  * url . URL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apubAcc  ap . Accountable , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  ( * gtsmodel . Account ,  ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Pre-fetch a transport for requesting username, used by later deref procedures. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tsport ,  err  :=  d . transportController . NewTransportForUsername ( ctx ,  requestUser ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 09:27:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "couldn't create transport: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 09:27:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . Username  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// A username was provided so we can attempt to webfinger, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this ensures up-to-date account domain, and handles some 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// edge cases where servers don't provide a preferred_username. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accUsername ,  accDomain ,  accURI ,  err  :=  d . fingerRemoteAccount ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tsport , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Domain , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  err  !=  nil  &&  account . URI  ==  "" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This is a new account (to us) with username@domain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// but failed webfinger, nothing more we can do. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  gtserror . Newf ( "error webfingering account: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  err  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Simply log this error and move on, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we already have an account URI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Errorf ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"error webfingering[1] remote account %s@%s: %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												account . Username ,  account . Domain ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 08:50:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  account . Domain  !=  accDomain : 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// After webfinger, we now have correct account domain from which we can do a final DB check. 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											alreadyAcc ,  err  :=  d . state . DB . GetAccountByUsernameDomain ( ctx ,  account . Username ,  accDomain ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  nil ,  gtserror . Newf ( "db error getting account after webfinger: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-08 17:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  alreadyAcc  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We had this account stored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// under discovered accountDomain. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Proceed with this account. 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												account  =  alreadyAcc 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 10:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Whether we had the account or not, we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// now have webfinger info relevant to the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// account, so fallthrough to set webfinger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// info on either the account we just found, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// or the stub account we were passed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fallthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 08:50:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Update account with latest info. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . URI  =  accURI . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Domain  =  accDomain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uri  =  accURI 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Specifically only update username if not already set. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Username  =  cmp . Or ( account . Username ,  accUsername ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  uri  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// No URI provided / found, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// must parse from account. 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uri ,  err  =  url . Parse ( account . URI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 08:50:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  gtserror . Newf ( "invalid uri %q: %w" ,  account . URI ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Check URI scheme ahead of time for more useful errs. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  uri . Scheme  !=  "http"  &&  uri . Scheme  !=  "https"  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 08:50:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  gtserror . Newf ( "invalid uri %q: scheme must be http(s)" ,  account . URI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BY  THIS  POINT  we  must  have  an  account  URI  set , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										either  provided ,  pinned  to  the  account ,  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obtained  via  webfinger  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check whether this account URI is a blocked domain / subdomain. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  blocked ,  err  :=  d . state . DB . IsDomainBlocked ( ctx ,  uri . Host ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "error checking blocked domain: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  blocked  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "%s is blocked" ,  uri . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Mark deref+update handshake start. 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d . startHandshake ( requestUser ,  uri ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  d . stopHandshake ( requestUser ,  uri ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  resolve  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  resolve  =  ( apubAcc  ==  nil ) ;  resolve  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// We were not given any (partial) ActivityPub 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// version of this account as a parameter. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Dereference latest version of the account. 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rsp ,  err  :=  tsport . Dereference ( ctx ,  uri ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  gtserror . Newf ( "error dereferencing %s: %w" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . SetUnretrievable ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Attempt to resolve ActivityPub acc from response. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apubAcc ,  err  =  ap . ResolveAccountable ( ctx ,  rsp . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Tidy up now done. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_  =  rsp . Body . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// ResolveAccountable will set gtserror.WrongType 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// on the returned error, so we don't need to do it here. 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  :=  gtserror . Newf ( "error resolving accountable %s: %w" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Check whether input URI and final returned URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// have changed (i.e. we followed some redirects). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  finalURIStr  :=  rsp . Request . URL . String ( ) ;  // 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finalURIStr  !=  uri . String ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// NOTE: this URI check + database call is performed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// AFTER reading and closing response body, for performance. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check whether we have this account stored under *final* URI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											alreadyAcc ,  err  :=  d . state . DB . GetAccountByURI ( ctx ,  finalURIStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  nil ,  gtserror . Newf ( "db error getting account after redirects: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-30 09:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  alreadyAcc  ==  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// nothing to do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  alreadyAcc . IsLocal ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Request eventually redirected to a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// local account. Return it as-is here. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  alreadyAcc ,  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// We had this account stored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// under discovered final URI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Proceed with this account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												account  =  alreadyAcc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Update the input URI to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the final determined URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// for later URI checks. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uri  =  rsp . Request . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BY  THIS  POINT  we  must  have  the  ActivityPub 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										representation  of  the  account ,  either  provided , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										or  obtained  via  a  dereference  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Convert the dereferenced AP account object to our GTS model. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We put this in the variable latestAcc because we might want 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to compare the provided account model with this fresh version, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// in order to check if anything changed since we last saw it. 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-23 17:44:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latestAcc ,  err  :=  d . converter . ASRepresentationToAccount ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apubAcc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Domain , 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										account . Username , 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// ASRepresentationToAccount will set Malformed on the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// returned error, so we don't need to do it here. 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  gtserror . Newf ( "error converting %s to gts model: %w" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . Username  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  accUsername  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-14 11:13:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Assume the host from the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// ActivityPub representation. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										id  :=  ap . GetJSONLDId ( apubAcc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  id  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . New ( "no id property found on person, or id was not an iri" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Get IRI host value. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accHost  :=  id . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// No username was provided, so no webfinger was attempted earlier. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 16:45:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Now we have a username we can attempt again, to ensure up-to-date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// accountDomain info. For this final attempt we should use the domain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// of the ID of the dereffed account, rather than the URI we were given. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This avoids cases where we were given a URI like 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// https://example.org/@someone@somewhere.else and we've been redirected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// from example.org to somewhere.else: we want to take somewhere.else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// as the accountDomain then, not the example.org we were redirected from. 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accUsername ,  latestAcc . Domain ,  _ ,  err  =  d . fingerRemoteAccount ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											tsport , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . Username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accHost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 16:45:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-14 11:13:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Webfingering account still failed, so we're not certain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// what the accountDomain actually is. Exit here for safety. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"error webfingering remote account %s@%s: %w" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												latestAcc . Username ,  accHost ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Specifically only update username if not already set. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestAcc . Username  =  cmp . Or ( latestAcc . Username ,  accUsername ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure the final parsed account URI matches 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-14 11:13:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// the input URI we fetched (or received) it as. 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  matches ,  err  :=  util . URIMatches ( 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-26 13:11:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uri , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										append ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ap . GetURL ( apubAcc ) ,       // account URL(s) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ap . GetJSONLDId ( apubAcc ) ,  // account URI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) ... , 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-26 13:11:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"error checking account uri %s: %w" , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-26 13:11:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											latestAcc . URI ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 09:01:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ! matches  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-14 11:13:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"account uri %s does not match %s" , 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-30 09:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											latestAcc . URI ,  uri , 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-14 11:13:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-01-30 09:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure this isn't a local account, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or a remote masquerading as such! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  latestAcc . IsLocal ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "cannot dereference local account %s" ,  uri ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get current time. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									now  :=  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Before expending any further serious compute, we need 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to ensure account keys haven't unexpectedly been changed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! verifyAccountKeysOnUpdate ( account ,  latestAcc ,  now ,  ! resolve )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  gtserror . Newf ( "account %s pubkey has changed (key rotation required?)" ,  uri ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BY  THIS  POINT  we  have  more  or  less  a  fullly - formed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										representation  of  the  target  account ,  derived  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										a  combination  of  webfinger  lookups  and  dereferencing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Further  fetching  beyond  this  point  is  for  peripheral 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-16 13:10:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										things  like  account  avatar ,  header ,  emojis ,  stats . 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Ensure internal db ID is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set and update fetch time. 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latestAcc . ID  =  account . ID 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									latestAcc . FetchedAt  =  now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc . UpdatedAt  =  now 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure the account's avatar media is populated, passing in existing to check for chages. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  d . fetchAccountAvatar ( ctx ,  requestUser ,  account ,  latestAcc ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "error fetching remote avatar for account %s: %v" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-09 09:27:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure the account's avatar media is populated, passing in existing to check for chages. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  d . fetchAccountHeader ( ctx ,  requestUser ,  account ,  latestAcc ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "error fetching remote header for account %s: %v" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch the latest remote account emoji IDs used in account display name/bio. 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  d . fetchAccountEmojis ( ctx ,  account ,  latestAcc ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 12:02:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										log . Errorf ( ctx ,  "error fetching remote emojis for account %s: %v" ,  uri ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  account . IsNew ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Prefer published/created time from 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// apubAcc, fall back to current time. 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  latestAcc . CreatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-13 15:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											latestAcc . CreatedAt  =  now 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-03 08:34:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This is new, put it in the database. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  :=  d . state . DB . PutAccount ( ctx ,  latestAcc ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-03 08:34:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( "error putting in database: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-26 14:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Prefer published time from apubAcc, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fall back to previous stored value. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  latestAcc . CreatedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . CreatedAt  =  account . CreatedAt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 20:03:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This is an existing account, update the model in the database. 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . UpdateAccount ( ctx ,  latestAcc ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  nil ,  gtserror . Newf ( "error updating database: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  latestAcc ,  apubAcc ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  fetchAccountAvatar (  
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									existingAcc  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  error  {  
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  latestAcc . AvatarRemoteURL  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// No avatar set on newest model, leave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// latest avatar attachment ID empty. 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for an existing stored media attachment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// specifically with unchanged remote URL we can use. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  existingAcc . AvatarMediaAttachmentID  !=  ""  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										existingAcc . AvatarRemoteURL  ==  latestAcc . AvatarRemoteURL  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Fetch the existing avatar media attachment with ID. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										existing ,  err  :=  d . state . DB . GetAttachmentByID ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											existingAcc . AvatarMediaAttachmentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  gtserror . Newf ( "error getting attachment %s: %w" ,  existingAcc . AvatarMediaAttachmentID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  existing  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Ensuring existing attachment is up-to-date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// and any recaching is performed if required. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											existing ,  err  :=  d . updateAttachment ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												requestUser , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												existing , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error updating existing attachment: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// specifically do NOT return nil here, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// we already have a model, we don't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// want to drop it from the account, just 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// log that an update for it failed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Set the avatar attachment on account model. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . AvatarMediaAttachment  =  existing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . AvatarMediaAttachmentID  =  existing . ID 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch newly changed avatar. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									attachment ,  err  :=  d . GetMedia ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										latestAcc . ID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestAcc . AvatarRemoteURL , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										media . AdditionalMediaInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Avatar :     util . Ptr ( true ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RemoteURL :  & latestAcc . AvatarRemoteURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  attachment  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  gtserror . Newf ( "error loading attachment %s: %w" ,  latestAcc . AvatarRemoteURL ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// non-fatal error occurred during loading, still use it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warnf ( ctx ,  "partially loaded attachment: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set the avatar attachment on account model. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc . AvatarMediaAttachment  =  attachment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc . AvatarMediaAttachmentID  =  attachment . ID 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  fetchAccountHeader (  
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									existingAcc  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  error  {  
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  latestAcc . HeaderRemoteURL  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// No header set on newest model, leave 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// latest header attachment ID empty. 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for an existing stored media attachment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// specifically with unchanged remote URL we can use. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  existingAcc . HeaderMediaAttachmentID  !=  ""  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										existingAcc . HeaderRemoteURL  ==  latestAcc . HeaderRemoteURL  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Fetch the existing header media attachment with ID. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										existing ,  err  :=  d . state . DB . GetAttachmentByID ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											existingAcc . HeaderMediaAttachmentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  gtserror . Newf ( "error getting attachment %s: %w" ,  existingAcc . HeaderMediaAttachmentID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  existing  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Ensuring existing attachment is up-to-date 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// and any recaching is performed if required. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											existing ,  err  :=  d . updateAttachment ( ctx , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												requestUser , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												existing , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nil , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												log . Errorf ( ctx ,  "error updating existing attachment: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-12 13:20:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// specifically do NOT return nil here, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// we already have a model, we don't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// want to drop it from the account, just 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// log that an update for it failed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Set the header attachment on account model. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . HeaderMediaAttachment  =  existing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											latestAcc . HeaderMediaAttachmentID  =  existing . ID 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-10 20:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch newly changed header. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									attachment ,  err  :=  d . GetMedia ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										latestAcc . ID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										latestAcc . HeaderRemoteURL , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										media . AdditionalMediaInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Header :     util . Ptr ( true ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RemoteURL :  & latestAcc . HeaderRemoteURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  attachment  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  gtserror . Newf ( "error loading attachment %s: %w" ,  latestAcc . HeaderRemoteURL ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// non-fatal error occurred during loading, still use it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warnf ( ctx ,  "partially loaded attachment: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-06 14:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set the header attachment on account model. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc . HeaderMediaAttachment  =  attachment 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									latestAcc . HeaderMediaAttachmentID  =  attachment . ID 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-22 20:46:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  fetchAccountEmojis (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									existing  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fetch the updated emojis for our account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									emojis ,  changed ,  err  :=  d . fetchEmojis ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										existing . Emojis , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Emojis , 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  gtserror . Newf ( "error fetching emojis: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! changed  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Use existing account emoji objects. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . EmojiIDs  =  existing . EmojiIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Emojis  =  existing . Emojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set latest emojis. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account . Emojis  =  emojis 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Iterate over and set changed emoji IDs. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account . EmojiIDs  =  make ( [ ] string ,  len ( emojis ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  emoji  :=  range  emojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . EmojiIDs [ i ]  =  emoji . ID 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-26 15:01:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  dereferenceAccountStats (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									account  * gtsmodel . Account , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  error  {  
						 
					
						
							
								
									
										
										
										
											2024-04-16 13:10:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure we have a stats model for this account. 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-02 12:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  d . state . DB . PopulateAccountStats ( ctx ,  account ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  gtserror . Newf ( "db error getting account stats: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-16 13:10:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We want to update stats by getting remote 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// followers/following/statuses counts for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If we fail getting any particular stat, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// it will just fall back to counting local. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Followers first. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  count ,  err  :=  d . countCollection ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . FollowersURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Log this but don't bail. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warnf ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"couldn't count followers for @%s@%s: %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Username ,  account . Domain ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  count  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Positive integer is useful! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Stats . FollowersCount  =  & count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Now following. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  count ,  err  :=  d . countCollection ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . FollowingURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Log this but don't bail. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warnf ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"couldn't count following for @%s@%s: %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Username ,  account . Domain ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  count  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Positive integer is useful! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Stats . FollowingCount  =  & count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Now statuses count. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  count ,  err  :=  d . countCollection ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . OutboxURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Log this but don't bail. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Warnf ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"couldn't count statuses for @%s@%s: %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											account . Username ,  account . Domain ,  err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  count  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Positive integer is useful! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Stats . StatusesCount  =  & count 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Update stats now. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  d . state . DB . UpdateAccountStats ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . Stats , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"followers_count" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"following_count" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"statuses_count" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  gtserror . Newf ( "db error updating account stats: %w" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// countCollection parses the given uriStr,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// dereferences the result as a collection  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// type, and returns total items as 0, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// a positive integer, or -1 if total items  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// cannot be counted.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Error will be returned for invalid non-empty  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// URIs or dereferencing isses.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  countCollection (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  context . Context , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uriStr  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requestUser  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  ( int ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  uriStr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uri ,  err  :=  url . Parse ( uriStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									collect ,  err  :=  d . dereferenceCollection ( ctx ,  requestUser ,  uri ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  collect . TotalItems ( ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// dereferenceAccountFeatured dereferences an account's featuredCollectionURI (if not empty). For each discovered status, this status will  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// be dereferenced (if necessary) and marked as pinned (if necessary). Then, old pins will be removed if they're not included in new pins.  
						 
					
						
							
								
									
										
										
										
											2023-10-23 10:58:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * Dereferencer )  dereferenceAccountFeatured ( ctx  context . Context ,  requestUser  string ,  account  * gtsmodel . Account )  error  {  
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uri ,  err  :=  url . Parse ( account . FeaturedCollectionURI ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									collect ,  err  :=  d . dereferenceCollection ( ctx ,  requestUser ,  uri ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get previous pinned statuses (we'll need these later). 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									wasPinned ,  err  :=  d . state . DB . GetAccountPinnedStatuses ( ctx ,  account . ID ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! errors . Is ( err ,  db . ErrNoEntries )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 13:08:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  gtserror . Newf ( "error getting account pinned statuses: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  statusURIs  [ ] * url . URL 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Get next collect item. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										item  :=  collect . NextItem ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  item  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Check for available IRI. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										itemIRI ,  _  :=  pub . ToId ( item ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  itemIRI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  itemIRI . Host  !=  uri . Host  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If this status doesn't share a host with its featured 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// collection URI, we shouldn't trust it. Just move on. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Already append this status URI to our slice. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We do this here so that even if we can't get 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the status in the next part for some reason, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we still know it was *meant* to be pinned. 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										statusURIs  =  append ( statusURIs ,  itemIRI ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Search for status by URI. Note this may return an existing model 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we have stored with an error from attempted update, so check both. 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										status ,  _ ,  _ ,  err  :=  d . getStatusByURI ( ctx ,  requestUser ,  itemIRI ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error getting status from featured collection %s: %v" ,  itemIRI ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-31 13:29:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  status  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// This is only unactionable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// if no status was returned. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// If the status was already pinned, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we don't need to do anything. 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! status . PinnedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  status . AccountURI  !=  account . URI  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Someone's pinned a status that doesn't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// belong to them, this doesn't work for us. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  status . BoostOfID  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-23 15:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Someone's pinned a boost. This 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// also doesn't work for us. (note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we check using BoostOfID since 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// BoostOfURI isn't *always* set). 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// All conditions are met for this status to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// be pinned, so we can finally update it. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										status . PinnedAt  =  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . UpdateStatus ( ctx ,  status ,  "pinned_at" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error updating status in featured collection %s: %v" ,  status . URI ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Now that we know which statuses are pinned, we should 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// *unpin* previous pinned statuses that aren't included. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								outerLoop :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  status  :=  range  wasPinned  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  statusURI  :=  range  statusURIs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  status . URI  ==  statusURI . String ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// This status is included in most recent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// pinned uris. No need to keep checking. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue  outerLoop 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Status was pinned before, but is not included 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// in most recent pinned uris, so unpin it now. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										status . PinnedAt  =  time . Time { } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-12 10:15:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  d . state . DB . UpdateStatus ( ctx ,  status ,  "pinned_at" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											log . Errorf ( ctx ,  "error unpinning status %s: %v" ,  status . URI ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:52:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}