2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  sql  =  require ( './sql' ) ;  
						 
					
						
							
								
									
										
										
										
											2019-01-05 21:49:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  sqlInit  =  require ( './sql_init' ) ;  
						 
					
						
							
								
									
										
										
										
											2018-04-01 21:27:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  optionService  =  require ( './options' ) ;  
						 
					
						
							
								
									
										
										
										
											2018-04-02 20:46:46 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  dateUtils  =  require ( './date_utils' ) ;  
						 
					
						
							
								
									
										
										
										
											2021-06-29 22:15:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  entityChangesService  =  require ( './entity_changes' ) ;  
						 
					
						
							
								
									
										
										
										
											2018-08-01 09:26:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  eventService  =  require ( './events' ) ;  
						 
					
						
							
								
									
										
										
										
											2018-11-06 14:23:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  cls  =  require ( '../services/cls' ) ;  
						 
					
						
							
								
									
										
										
										
											2019-09-01 22:09:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  protectedSessionService  =  require ( '../services/protected_session' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  log  =  require ( '../services/log' ) ;  
						 
					
						
							
								
									
										
										
										
											2020-05-12 10:28:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  utils  =  require ( '../services/utils' ) ;  
						 
					
						
							
								
									
										
										
										
											2019-11-09 11:58:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  noteRevisionService  =  require ( '../services/note_revisions' ) ;  
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  request  =  require ( './request' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  path  =  require ( 'path' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  url  =  require ( 'url' ) ;  
						 
					
						
							
								
									
										
										
										
											2021-06-29 22:15:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  becca  =  require ( '../becca/becca' ) ;  
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  BBranch  =  require ( '../becca/entities/bbranch' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  BNote  =  require ( '../becca/entities/bnote' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  BAttribute  =  require ( '../becca/entities/battribute' ) ;  
						 
					
						
							
								
									
										
										
										
											2022-05-15 15:21:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  dayjs  =  require ( "dayjs" ) ;  
						 
					
						
							
								
									
										
										
										
											2022-12-09 16:13:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  htmlSanitizer  =  require ( "./html_sanitizer" ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  ValidationError  =  require ( "../errors/validation_error" ) ;  
						 
					
						
							
								
									
										
										
										
											2022-12-16 16:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  noteTypesService  =  require ( "./note_types" ) ;  
						 
					
						
							
								
									
										
										
										
											2023-04-16 23:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  fs  =  require ( "fs" ) ;  
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/** @param {BNote} parentNote */  
						 
					
						
							
								
									
										
										
										
											2023-03-19 22:23:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  getNewNotePosition ( parentNote )  {  
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:08:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( parentNote . isLabelTruthy ( 'newNotesOnTop' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 22:23:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  minNotePos  =  parentNote . getChildBranches ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . reduce ( ( min ,  note )  =>  Math . min ( min ,  note . notePosition ) ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 22:23:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  minNotePos  -  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  maxNotePos  =  parentNote . getChildBranches ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . reduce ( ( max ,  note )  =>  Math . max ( max ,  note . notePosition ) ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-17 20:52:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 22:23:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  maxNotePos  +  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 22:23:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/** @param {BNote} note */  
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  triggerNoteTitleChanged ( note )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eventService . emit ( eventService . NOTE _TITLE _CHANGED ,  note ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-01 09:26:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 11:09:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  deriveMime ( type ,  mime )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( ` Note type is a required param ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-31 12:29:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 11:09:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( mime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  mime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-16 16:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  noteTypesService . getDefaultMimeForNoteType ( type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-01-27 17:18:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { BNote }  parentNote 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { BNote }  childNote 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  copyChildAttributes ( parentNote ,  childNote )  {  
						 
					
						
							
								
									
										
										
										
											2023-02-27 21:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  hasAlreadyTemplate  =  childNote . hasRelation ( 'template' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-14 21:08:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( const  attr  of  parentNote . getAttributes ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( attr . name . startsWith ( "child:" ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 21:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  name  =  attr . name . substr ( 6 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( hasAlreadyTemplate  &&  attr . type  ===  'relation'  &&  name  ===  'template' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // if the note already has a template, it means the template was chosen by the user explicitly
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // in the menu. In that case we should override the default templates defined in the child: attrs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            new  BAttribute ( { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                noteId :  childNote . noteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                type :  attr . type , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 21:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                name :  name , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                value :  attr . value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                position :  attr . position , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                isInheritable :  attr . isInheritable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) . save ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-17 12:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-03-17 12:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/** @param {BNote} parentNote */  
						 
					
						
							
								
									
										
										
										
											2022-05-15 15:21:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  getNewNoteTitle ( parentNote )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    let  title  =  "new note" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  titleTemplate  =  parentNote . getLabelValue ( 'titleTemplate' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( titleTemplate  !==  null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  now  =  dayjs ( cls . getLocalNowDateTime ( )  ||  new  Date ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // "officially" injected values:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // - now
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // - parentNote
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-21 15:19:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            title  =  eval ( ` \` ${ titleTemplate } \` ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 15:21:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  catch  ( e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            log . error ( ` Title template of note ' ${ parentNote . noteId } ' failed with:  ${ e . message } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-06 23:09:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // this isn't in theory a good place to sanitize title, but this will catch a lot of XSS attempts
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // title is supposed to contain text only (not HTML) and be printed text only, but given the number of usages
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // it's difficult to guarantee correct handling in all cases
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    title  =  htmlSanitizer . sanitize ( title ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 15:21:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-27 23:43:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  getAndValidateParent ( params )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  parentNote  =  becca . notes [ params . parentNoteId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parentNote )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 22:16:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  ValidationError ( ` Parent note ' ${ params . parentNoteId } ' was not found. ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-27 23:43:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-24 12:26:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( parentNote . type  ===  'launcher'  &&  parentNote . noteId  !==  '_lbBookmarks' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-09 16:48:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  ValidationError ( ` Creating child notes into launcher notes is not allowed. ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-21 16:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( [ '_lbAvailableLaunchers' ,  '_lbVisibleLaunchers' ] . includes ( params . parentNoteId )  &&  params . type  !==  'launcher' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-18 20:12:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  ValidationError ( ` Only 'launcher' notes can be created in parent ' ${ params . parentNoteId } ' ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-13 11:34:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! params . ignoreForbiddenParents )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( [ '_lbRoot' ,  '_hidden' ] . includes ( parentNote . noteId ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ||  parentNote . noteId . startsWith ( "_lbTpl" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ||  parentNote . isOptions ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            throw  new  ValidationError ( ` Creating child notes into ' ${ parentNote . noteId } ' is not allowed. ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-27 23:43:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  parentNote ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Following  object  properties  are  mandatory : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { string }  parentNoteId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { string }  title 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { * }  content 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 23:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  -  { string }  type  -  text ,  code ,  file ,  image ,  search ,  book ,  relationMap ,  canvas ,  render 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Following  are  optional  ( have  defaults ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { string }  mime  -  value  is  derived  from  default  mimes  for  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { boolean }  isProtected  -  default  is  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { boolean }  isExpanded  -  default  is  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { string }  prefix  -  default  is  empty  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  -  { integer }  notePosition  -  default  is  last  existing  notePosition  in  a  parent  +  10 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  params 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-05 23:38:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ returns  { { note :  BNote ,  branch :  BBranch } } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  createNewNote ( params )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-27 23:43:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  parentNote  =  getAndValidateParent ( params ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 19:33:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( params . title  ===  null  ||  params . title  ===  undefined )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-15 15:21:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        params . title  =  getNewNoteTitle ( parentNote ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 23:06:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 19:33:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( params . content  ===  null  ||  params . content  ===  undefined )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( ` Note content must be set ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 23:10:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 22:20:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  sql . transactional ( ( )  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 21:34:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        let  note ,  branch ,  isEntityEventsDisabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            isEntityEventsDisabled  =  cls . isEntityEventsDisabled ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! isEntityEventsDisabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // it doesn't make sense to run note creation events on a partially constructed note, so
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // defer them until note creation is completed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cls . disableEntityEvents ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-27 14:44:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // TODO: think about what can happen if the note already exists with the forced ID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       I guess on DB it's going to be fine, but becca references between entities
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       might get messed up (two Note instance for the same ID existing in the references)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            note  =  new  BNote ( { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 21:34:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                noteId :  params . noteId ,  // optionally can force specific noteId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                title :  params . title , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                isProtected :  ! ! params . isProtected , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                type :  params . type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                mime :  deriveMime ( params . type ,  params . mime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) . save ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note . setContent ( params . content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            branch  =  new  BBranch ( { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 21:34:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                noteId :  note . noteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                parentNoteId :  params . parentNoteId , 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-19 22:23:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                notePosition :  params . notePosition  !==  undefined  ?  params . notePosition  :  getNewNotePosition ( parentNote ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 21:34:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                prefix :  params . prefix , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                isExpanded :  ! ! params . isExpanded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) . save ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        finally  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! isEntityEventsDisabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // re-enable entity events only if there were previously enabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // (they can be disabled in case of import)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                cls . enableEntityEvents ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 21:32:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        asyncPostProcessContent ( note ,  params . content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 21:32:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 23:27:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( params . templateNoteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! becca . getNote ( params . templateNoteId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                throw  new  Error ( ` Template note ' ${ params . templateNoteId } ' does not exist. ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 21:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            note . addRelation ( 'template' ,  params . templateNoteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-06 20:31:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // no special handling for ~inherit since it doesn't matter if it's assigned with the note creation or later
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 23:27:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 21:07:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        copyChildAttributes ( parentNote ,  note ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 21:32:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        triggerNoteTitleChanged ( note ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 21:34:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eventService . emit ( eventService . ENTITY _CREATED ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entityName :  'notes' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entity :  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eventService . emit ( eventService . ENTITY _CREATED ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entityName :  'branches' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            entity :  branch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eventService . emit ( eventService . CHILD _NOTE _CREATED ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            childNote :  note , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parentNote :  parentNote 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 21:32:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . info ( ` Created new note ' ${ note . noteId } ', branch ' ${ branch . branchId } ' of type ' ${ note . type } ', mime ' ${ note . mime } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-31 21:25:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 21:32:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            branch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  createNewNoteWithTarget ( target ,  targetBranchId ,  params )  {  
						 
					
						
							
								
									
										
										
										
											2019-11-16 17:00:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! params . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  parentNote  =  becca . notes [ params . parentNoteId ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 17:00:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // code note type can be inherited, otherwise text is default
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        params . type  =  parentNote . type  ===  'code'  ?  'code'  :  'text' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        params . mime  =  parentNote . type  ===  'code'  ?  parentNote . mime  :  'text/html' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( target  ===  'into' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  createNewNote ( params ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( target  ===  'after' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  afterBranch  =  becca . branches [ targetBranchId ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // not updating utcDateModified to avoid having to sync whole rows
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        sql . execute ( 'UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0' , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            [ params . parentNoteId ,  afterBranch . notePosition ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:24:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        params . notePosition  =  afterBranch . notePosition  +  10 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  retObject  =  createNewNote ( params ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-02 23:43:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        entityChangesService . addNoteReorderingEntityChange ( params . parentNoteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-24 22:15:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  retObject ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 22:16:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( ` Unknown target ' ${ target } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { BNote }  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { boolean }  protect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { boolean }  includingSubTree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { TaskContext }  taskContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  protectNoteRecursively ( note ,  protect ,  includingSubTree ,  taskContext )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protectNote ( note ,  protect ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 09:58:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    taskContext . increaseProgressCount ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-26 16:37:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( includingSubTree )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  child  of  note . getChildNotes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            protectNoteRecursively ( child ,  protect ,  includingSubTree ,  taskContext ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-26 16:37:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { BNote }  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { boolean }  protect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  protectNote ( note ,  protect )  {  
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! protectedSessionService . isProtectedSessionAvailable ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( ` Cannot (un)protect note ' ${ note . noteId } ' with protect flag ' ${ protect } ' without active protected session ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 22:49:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( protect  !==  note . isProtected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  content  =  note . getContent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-04 14:46:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 22:49:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            note . isProtected  =  protect ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-14 23:16:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // see https://github.com/zadam/trilium/issues/3523
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // IIRC a zero-sized buffer can be returned as null from the database
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( content  !==  null )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-14 00:01:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // this will force de/encryption
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                note . setContent ( content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-04 14:46:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 22:49:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            note . save ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        noteRevisionService . protectNoteRevisions ( note ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 22:49:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    catch  ( e )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . error ( ` Could not un/protect note ' ${ note . noteId } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 22:49:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-15 00:04:26 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  checkImageAttachments ( note ,  content )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  re  =  /src="[^"]*api\/attachments\/([a-zA-Z0-9_]+)\/image/g ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  foundAttachmentIds  =  new  Set ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    let  match ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( match  =  re . exec ( content ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        foundAttachmentIds . add ( match [ 1 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 00:01:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  imageAttachments  =  note . getAttachmentByRole ( 'image' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  attachment  of  imageAttachments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  imageInContent  =  foundAttachmentIds . has ( attachment . attachmentId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( attachment . utcDateScheduledForErasureSince  &&  imageInContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            attachment . utcDateScheduledForErasureSince  =  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            attachment . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ! attachment . utcDateScheduledForErasureSince  &&  ! imageInContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            attachment . utcDateScheduledForErasureSince  =  dateUtils . utcNowDateTime ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            attachment . save ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 00:01:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  existingAttachmentIds  =  new  Set ( imageAttachments . map ( att  =>  att . attachmentId ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  unknownAttachmentIds  =  Array . from ( foundAttachmentIds ) . filter ( foundAttId  =>  ! existingAttachmentIds . has ( foundAttId ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  unknownAttachments  =  becca . getAttachments ( unknownAttachmentIds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 00:01:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( const  unknownAttachment  of  unknownAttachments )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 00:01:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // the attachment belongs to a different note (was copy pasted), we need to make a copy for this note.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  newAttachment  =  unknownAttachment . copy ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        newAttachment . parentId  =  note . noteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        newAttachment . setContent ( unknownAttachment . getContent ( ) ,  {  forceSave :  true  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        content  =  content . replace ( ` api/attachments/ ${ unknownAttachment . attachmentId } /image ` ,  ` api/attachments/ ${ newAttachment . attachmentId } /image ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 22:46:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        log . info ( ` Copied attachment ' ${ unknownAttachment . attachmentId } ' to new ' ${ newAttachment . attachmentId } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-25 00:01:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        forceFrontendReload :  unknownAttachments . length  >  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  findImageLinks ( content ,  foundLinks )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:39:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  re  =  /src="[^"]*api\/images\/([a-zA-Z0-9_]+)\//g ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  match ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( match  =  re . exec ( content ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foundLinks . push ( { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-23 20:54:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name :  'imageLink' , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value :  match [ 1 ] 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // removing absolute references to server to keep it working between instances
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-22 23:03:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // we also omit / at the beginning to keep the paths relative
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  content . replace ( /src="[^"]*\/api\/images\//g ,  'src="api/images/' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  findInternalLinks ( content ,  foundLinks )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:39:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  re  =  /href="[^"]*#root[a-zA-Z0-9_\/]*\/([a-zA-Z0-9_]+)\/?"/g ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  match ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( match  =  re . exec ( content ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foundLinks . push ( { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-23 20:54:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name :  'internalLink' , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value :  match [ 1 ] 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // removing absolute references to server to keep it working between instances
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  content . replace ( /href="[^"]*#root/g ,  'href="#root' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-10 21:41:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  findIncludeNoteLinks ( content ,  foundLinks )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-28 23:39:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  re  =  /<section class="include-note[^>]+data-note-id="([a-zA-Z0-9_]+)"[^>]*>/g ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-10 21:41:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  match ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( match  =  re . exec ( content ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foundLinks . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name :  'includeNoteLink' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value :  match [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  findRelationMapLinks ( content ,  foundLinks )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  obj  =  JSON . parse ( content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  note  of  obj . notes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        foundLinks . push ( { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-23 20:54:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            name :  'relationMapLink' , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value :  note . noteId 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-02 23:22:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  imageUrlToAttachmentIdMapping  =  { } ;  
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								async  function  downloadImage ( noteId ,  imageUrl )  {  
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    try  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-16 23:11:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        let  imageBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( imageUrl . toLowerCase ( ) . startsWith ( "file://" ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            imageBuffer  =  await  new  Promise ( ( res ,  rej )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  localFilePath  =  imageUrl . substr ( "file://" . length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  fs . readFile ( localFilePath ,  ( err ,  data )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        rej ( err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        res ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            imageBuffer  =  await  request . getImage ( imageUrl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  parsedUrl  =  url . parse ( imageUrl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  title  =  path . basename ( parsedUrl . pathname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  imageService  =  require ( '../services/image' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  { attachment }  =  imageService . saveImageToAttachment ( noteId ,  imageBuffer ,  title ,  true ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        imageUrlToAttachmentIdMapping [ imageUrl ]  =  attachment . attachmentId ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . info ( ` Download of ' ${ imageUrl } ' succeeded and was saved as image attachment ' ${ attachment . attachmentId } ' of note ' ${ noteId } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    catch  ( e )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . error ( ` Download of ' ${ imageUrl } ' for note ' ${ noteId } ' failed with error:  ${ e . message }   ${ e . stack } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/** url => download promise */  
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  downloadImagePromises  =  { } ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  replaceUrl ( content ,  url ,  attachment )  {  
						 
					
						
							
								
									
										
										
										
											2020-07-26 23:47:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  quotedUrl  =  utils . quoteRegex ( url ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 18:21:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-17 22:40:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  content . replace ( new  RegExp ( ` \\ s+src=[ \" '] ${ quotedUrl } [ \" '] ` ,  "ig" ) ,  `  src="api/attachments/ ${ encodeURIComponent ( attachment . title ) } /image" ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  downloadImages ( noteId ,  content )  {  
						 
					
						
							
								
									
										
										
										
											2022-05-21 14:00:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! optionService . getOptionBool ( "downloadImagesAutomatically" ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-03 23:33:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  imageRe  =  /<img[^>]*?\ssrc=['"]([^'">]+)['"]/ig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    let  imageMatch ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-03 23:33:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( imageMatch  =  imageRe . exec ( content ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  url  =  imageMatch [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 22:58:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  inlineImageMatch  =  /^data:image\/[a-z]+;base64,/ . exec ( url ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( inlineImageMatch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  imageBase64  =  url . substr ( inlineImageMatch [ 0 ] . length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  imageBuffer  =  Buffer . from ( imageBase64 ,  'base64' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  imageService  =  require ( '../services/image' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 21:48:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  { note }  =  imageService . saveImage ( noteId ,  imageBuffer ,  "inline image" ,  true ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 22:58:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-05 22:40:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  sanitizedTitle  =  note . title . replace ( /[^a-z0-9-.]/gi ,  "" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-21 15:19:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            content  =  ` ${ content . substr ( 0 ,  imageMatch . index ) } <img src="api/images/ ${ note . noteId } / ${ sanitizedTitle } " ${ content . substr ( imageMatch . index  +  imageMatch [ 0 ] . length ) } ` ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 22:58:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-17 22:40:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( ! url . includes ( 'api/images/' )  &&  ! /api\/attachments\/.+\/image\/?.*/ . test ( url ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-26 22:58:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // this is an exception for the web clipper's "imageId"
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-03 14:33:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            &&  ( url . length  !==  20  ||  url . toLowerCase ( ) . startsWith ( 'http' ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( url  in  imageUrlToAttachmentIdMapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  attachment  =  becca . getAttachment ( imageUrlToAttachmentIdMapping [ url ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( ! attachment )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    delete  imageUrlToAttachmentIdMapping [ url ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    content  =  replaceUrl ( content ,  url ,  attachment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 23:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( url  in  downloadImagePromises )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // download is already in progress
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // this is done asynchronously, it would be too slow to wait for the download
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // given that save can be triggered very often
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            downloadImagePromises [ url ]  =  downloadImage ( noteId ,  url ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 18:21:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Promise . all ( Object . values ( downloadImagePromises ) ) . then ( ( )  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        setTimeout ( ( )  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // the normal expected flow of the offline image saving is that users will paste the image(s)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // which will get asynchronously downloaded, during that time they keep editing the note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // once the download is finished, the image note representing downloaded image will be used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // to replace the IMG link.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-18 23:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // However, there's another flow where user pastes the image and leaves the note before the images
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // are downloaded and the IMG references are not updated. For this occassion we have this code
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // which upon the download of all the images will update the note if the links have not been fixed before
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            sql . transactional ( ( )  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  imageNotes  =  becca . getNotes ( Object . values ( imageUrlToAttachmentIdMapping ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-02 11:23:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  origNote  =  becca . getNote ( noteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-21 20:18:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! origNote )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    log . error ( ` Cannot find note ' ${ noteId } ' to replace image link. ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-21 20:18:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  origContent  =  origNote . getContent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 23:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                let  updatedContent  =  origContent ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-16 20:13:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                for  ( const  url  in  imageUrlToAttachmentIdMapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  imageNote  =  imageNotes . find ( note  =>  note . noteId  ===  imageUrlToAttachmentIdMapping [ url ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 23:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( imageNote  &&  ! imageNote . isDeleted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        updatedContent  =  replaceUrl ( updatedContent ,  url ,  imageNote ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 23:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // update only if the links have not been already fixed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( updatedContent  !==  origContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    origNote . setContent ( updatedContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 21:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    asyncPostProcessContent ( origNote ,  updatedContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-03 14:33:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    console . log ( ` Fixed the image links for note ' ${ noteId } ' to the offline saved. ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 23:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ,  5000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 18:21:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  content ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-25 11:28:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  saveLinks ( note ,  content )  {  
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:20:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ( note . type  !==  'text'  &&  note . type  !==  'relationMap' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ||  ( note . isProtected  &&  ! protectedSessionService . isProtectedSessionAvailable ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            forceFrontendReload :  false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 22:09:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  foundLinks  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    let  forceFrontendReload  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-11 09:50:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( note . type  ===  'text' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        content  =  downloadImages ( note . noteId ,  content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-03 14:33:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        content  =  findImageLinks ( content ,  foundLinks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        content  =  findInternalLinks ( content ,  foundLinks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-10 21:41:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        content  =  findIncludeNoteLinks ( content ,  foundLinks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        ( { forceFrontendReload ,  content }  =  checkImageAttachments ( note ,  content ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 23:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( note . type  ===  'relationMap' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        findRelationMapLinks ( content ,  foundLinks ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:20:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( ` Unrecognized type ' ${ note . type } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-16 23:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:19:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  existingLinks  =  note . getRelations ( ) . filter ( rel  => 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [ 'internalLink' ,  'imageLink' ,  'relationMapLink' ,  'includeNoteLink' ] . includes ( rel . name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( const  foundLink  of  foundLinks )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:19:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  targetNote  =  becca . notes [ foundLink . value ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! targetNote )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:06:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 20:35:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  existingLink  =  existingLinks . find ( existingLink  => 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            existingLink . value  ===  foundLink . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            &&  existingLink . name  ===  foundLink . name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 11:08:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! existingLink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  newLink  =  new  BAttribute ( { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 22:15:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                noteId :  note . noteId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 16:06:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                type :  'relation' , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                name :  foundLink . name , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-27 22:47:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                value :  foundLink . value , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-02 22:53:01 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ) . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-05 15:35:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            existingLinks . push ( newLink ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-15 21:04:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // else the link exists, so we don't need to do anything
 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 11:08:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // marking links as deleted if they are not present on the page anymore
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 20:17:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  unusedLinks  =  existingLinks . filter ( existingLink  =>  ! foundLinks . some ( foundLink  => 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 20:12:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                    existingLink . value  ===  foundLink . value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    &&  existingLink . name  ===  foundLink . name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-08 11:08:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( const  unusedLink  of  unusedLinks )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 21:19:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        unusedLink . markAsDeleted ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:00:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  {  forceFrontendReload ,  content  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-06 22:38:53 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/** @param {BNote} note */  
						 
					
						
							
								
									
										
										
										
											2022-06-02 17:25:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  saveNoteRevisionIfNeeded ( note )  {  
						 
					
						
							
								
									
										
										
										
											2019-12-02 20:21:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // files and images are versioned separately
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( note . type  ===  'file'  ||  note . type  ===  'image'  ||  note . hasLabel ( 'disableVersioning' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-06 21:29:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 12:56:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  now  =  new  Date ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  noteRevisionSnapshotTimeInterval  =  parseInt ( optionService . getOption ( 'noteRevisionSnapshotTimeInterval' ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 19:52:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  revisionCutoff  =  dateUtils . utcDateTimeStr ( new  Date ( now . getTime ( )  -  noteRevisionSnapshotTimeInterval  *  1000 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 12:31:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  existingNoteRevisionId  =  sql . getValue ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 22:35:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND utcDateCreated >= ?" ,  [ note . noteId ,  revisionCutoff ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 22:15:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-31 12:49:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  msSinceDateCreated  =  now . getTime ( )  -  dateUtils . parseDateTime ( note . utcDateCreated ) . getTime ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 22:15:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-06 21:29:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! existingNoteRevisionId  &&  msSinceDateCreated  >=  noteRevisionSnapshotTimeInterval  *  1000 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-02 17:25:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        note . saveNoteRevision ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-31 22:15:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 14:49:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  updateNoteData ( noteId ,  content )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-02 11:23:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  note  =  becca . getNote ( noteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 12:56:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 22:35:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! note . isContentAvailable ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( ` Note ' ${ noteId } ' is not available for change! ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-30 22:18:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-02 17:25:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    saveNoteRevisionIfNeeded ( note ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  {  forceFrontendReload ,  content :  newContent  }  =  saveLinks ( note ,  content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-06 22:39:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    note . setContent ( newContent ,  {  forceFrontendReload  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2021-05-09 11:12:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { string }  noteId 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { TaskContext }  taskContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 11:12:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  undeleteNote ( noteId ,  taskContext )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  note  =  sql . getRow ( "SELECT * FROM notes WHERE noteId = ?" ,  [ noteId ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! note . isDeleted )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-19 23:36:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . error ( ` Note ' ${ noteId } ' is not deleted and thus cannot be undeleted. ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 11:12:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  undeletedParentBranchIds  =  getUndeletedParentBranchIds ( noteId ,  note . deleteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( undeletedParentBranchIds . length  ===  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // cannot undelete if there's no undeleted parent
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( const  parentBranchId  of  undeletedParentBranchIds )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 11:12:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        undeleteBranch ( parentBranchId ,  note . deleteId ,  taskContext ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { string }  branchId 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { string }  deleteId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { TaskContext }  taskContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  undeleteBranch ( branchId ,  deleteId ,  taskContext )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  branch  =  sql . getRow ( "SELECT * FROM branches WHERE branchId = ?" ,  [ branchId ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! branch . isDeleted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  note  =  sql . getRow ( "SELECT * FROM notes WHERE noteId = ?" ,  [ branch . noteId ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( note . isDeleted  &&  note . deleteId  !==  deleteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    new  BBranch ( branch ) . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    taskContext . increaseProgressCount ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( note . isDeleted  &&  note . deleteId  ===  deleteId )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 23:38:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // becca entity was already created as skeleton in "new Branch()" above
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  noteEntity  =  becca . getNote ( note . noteId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        noteEntity . updateFromRow ( note ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        noteEntity . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  attributes  =  sql . getRows ( ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                SELECT  *  FROM  attributes  
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                WHERE  isDeleted  =  1  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  AND  deleteId  =  ?  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                  AND  ( noteId  =  ?  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                           OR  ( type  =  'relation'  AND  value  =  ? ) ) ` , [deleteId, note.noteId, note.noteId]);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  attribute  of  attributes )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 09:43:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // relation might point to a note which hasn't been undeleted yet and would thus throw up
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            new  BAttribute ( attribute ) . save ( { skipValidation :  true } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  childBranchIds  =  sql . getColumn ( ` 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 11:12:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            SELECT  branches . branchId 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            FROM  branches 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            WHERE  branches . isDeleted  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              AND  branches . deleteId  =  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								              AND  branches . parentNoteId  =  ? ` , [deleteId, note.noteId]);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  childBranchId  of  childBranchIds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            undeleteBranch ( childBranchId ,  deleteId ,  taskContext ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2023-01-05 23:38:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ returns  return  deleted  branchIds  of  an  undeleted  parent  note 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 22:01:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  getUndeletedParentBranchIds ( noteId ,  deleteId )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  sql . getColumn ( ` 
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-02 19:59:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    SELECT  branches . branchId 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    FROM  branches 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    JOIN  notes  AS  parentNote  ON  parentNote . noteId  =  branches . parentNoteId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    WHERE  branches . noteId  =  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      AND  branches . isDeleted  =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      AND  branches . deleteId  =  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      AND  parentNote . isDeleted  =  0 ` , [noteId, deleteId]);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  scanForLinks ( note ,  content )  {  
						 
					
						
							
								
									
										
										
										
											2022-12-06 23:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! note  ||  ! [ 'text' ,  'relationMap' ] . includes ( note . type ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 20:35:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 22:09:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    try  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        sql . transactional ( ( )  =>  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  {  forceFrontendReload ,  content :  newContent  }  =  saveLinks ( note ,  content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 20:35:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( content  !==  newContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                note . setContent ( newContent ,  {  forceFrontendReload  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-20 00:11:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 22:09:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    catch  ( e )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-03 10:23:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        log . error ( ` Could not scan for links note ' ${ note . noteId } ':  ${ e . message }   ${ e . stack } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 22:09:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 20:35:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
									
										
										
										
											2023-04-14 16:49:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ param  { BNote }  note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ param  { string }  content 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Things  which  have  to  be  executed  after  updating  content ,  but  asynchronously  ( separate  transaction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								async  function  asyncPostProcessContent ( note ,  content )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    scanForLinks ( note ,  content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseNotes ( noteIdsToErase )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( noteIdsToErase . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 22:11:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 22:32:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sql . executeMany ( ` DELETE FROM notes WHERE noteId IN (???) ` ,  noteIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 21:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setEntityChangesAsErased ( sql . getManyRows ( ` SELECT * FROM entity_changes WHERE entityName = 'notes' AND entityId IN (???) ` ,  noteIdsToErase ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-01 10:23:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // we also need to erase all "dependent" entities of the erased notes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  branchIdsToErase  =  sql . getManyRows ( ` SELECT branchId FROM branches WHERE noteId IN (???) ` ,  noteIdsToErase ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . map ( row  =>  row . branchId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseBranches ( branchIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  attributeIdsToErase  =  sql . getManyRows ( ` SELECT attributeId FROM attributes WHERE noteId IN (???) ` ,  noteIdsToErase ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . map ( row  =>  row . attributeId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseAttributes ( attributeIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  noteRevisionIdsToErase  =  sql . getManyRows ( ` SELECT noteRevisionId FROM note_revisions WHERE noteId IN (???) ` ,  noteIdsToErase ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        . map ( row  =>  row . noteRevisionId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-16 14:36:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    noteRevisionService . eraseNoteRevisions ( noteRevisionIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    log . info ( ` Erased notes:  ${ JSON . stringify ( noteIdsToErase ) } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 21:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  setEntityChangesAsErased ( entityChanges )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  ec  of  entityChanges )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ec . isErased  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        entityChangesService . addEntityChange ( ec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseBranches ( branchIdsToErase )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( branchIdsToErase . length  ===  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 22:26:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sql . executeMany ( ` DELETE FROM branches WHERE branchId IN (???) ` ,  branchIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 22:29:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 21:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setEntityChangesAsErased ( sql . getManyRows ( ` SELECT * FROM entity_changes WHERE entityName = 'branches' AND entityId IN (???) ` ,  branchIdsToErase ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 22:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    log . info ( ` Erased branches:  ${ JSON . stringify ( branchIdsToErase ) } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  eraseAttributes ( attributeIdsToErase )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( attributeIdsToErase . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sql . executeMany ( ` DELETE FROM attributes WHERE attributeId IN (???) ` ,  attributeIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 21:19:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setEntityChangesAsErased ( sql . getManyRows ( ` SELECT * FROM entity_changes WHERE entityName = 'attributes' AND entityId IN (???) ` ,  attributeIdsToErase ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-01 22:25:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    log . info ( ` Erased attributes:  ${ JSON . stringify ( attributeIdsToErase ) } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseAttachments ( attachmentIdsToErase )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( attachmentIdsToErase . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sql . executeMany ( ` DELETE FROM attachments WHERE attachmentId IN (???) ` ,  attachmentIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    setEntityChangesAsErased ( sql . getManyRows ( ` SELECT * FROM entity_changes WHERE entityName = 'attachments' AND entityId IN (???) ` ,  attachmentIdsToErase ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    log . info ( ` Erased attachments:  ${ JSON . stringify ( attachmentIdsToErase ) } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  eraseUnusedBlobs ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  unusedBlobIds  =  sql . getColumn ( ` 
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 23:04:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        SELECT  blobs . blobId 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        FROM  blobs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        LEFT  JOIN  notes  ON  notes . blobId  =  blobs . blobId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        LEFT  JOIN  attachments  ON  attachments . blobId  =  blobs . blobId 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 22:16:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        LEFT  JOIN  note _revisions  ON  note _revisions . blobId  =  blobs . blobId 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 21:01:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        WHERE  notes . noteId  IS  NULL  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          AND  attachments . attachmentId  IS  NULL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          AND  note _revisions . noteRevisionId  IS  NULL ` );
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 22:16:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( unusedBlobIds . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sql . executeMany ( ` DELETE FROM blobs WHERE blobId IN (???) ` ,  unusedBlobIds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    setEntityChangesAsErased ( sql . getManyRows ( ` SELECT * FROM entity_changes WHERE entityName = 'blobs' AND entityId IN (???) ` ,  unusedBlobIds ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    log . info ( ` Erased unused blobs:  ${ JSON . stringify ( unusedBlobIds ) } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseDeletedEntities ( eraseEntitiesAfterTimeInSeconds  =  null )  {  
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // this is important also so that the erased entity changes are sent to the connected clients
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sql . transactional ( ( )  =>  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( eraseEntitiesAfterTimeInSeconds  ===  null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            eraseEntitiesAfterTimeInSeconds  =  optionService . getOptionInt ( 'eraseEntitiesAfterTimeInSeconds' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  cutoffDate  =  new  Date ( Date . now ( )  -  eraseEntitiesAfterTimeInSeconds  *  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  noteIdsToErase  =  sql . getColumn ( "SELECT noteId FROM notes WHERE isDeleted = 1 AND utcDateModified <= ?" ,  [ dateUtils . utcDateTimeStr ( cutoffDate ) ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        eraseNotes ( noteIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  branchIdsToErase  =  sql . getColumn ( "SELECT branchId FROM branches WHERE isDeleted = 1 AND utcDateModified <= ?" ,  [ dateUtils . utcDateTimeStr ( cutoffDate ) ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        eraseBranches ( branchIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  attributeIdsToErase  =  sql . getColumn ( "SELECT attributeId FROM attributes WHERE isDeleted = 1 AND utcDateModified <= ?" ,  [ dateUtils . utcDateTimeStr ( cutoffDate ) ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        eraseAttributes ( attributeIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  attachmentIdsToErase  =  sql . getColumn ( "SELECT attachmentId FROM attachments WHERE isDeleted = 1 AND utcDateModified <= ?" ,  [ dateUtils . utcDateTimeStr ( cutoffDate ) ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eraseAttachments ( attachmentIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eraseUnusedBlobs ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 11:04:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-01 10:23:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseNotesWithDeleteId ( deleteId )  {  
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  noteIdsToErase  =  sql . getColumn ( "SELECT noteId FROM notes WHERE isDeleted = 1 AND deleteId = ?" ,  [ deleteId ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseNotes ( noteIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  branchIdsToErase  =  sql . getColumn ( "SELECT branchId FROM branches WHERE isDeleted = 1 AND deleteId = ?" ,  [ deleteId ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseBranches ( branchIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  attributeIdsToErase  =  sql . getColumn ( "SELECT attributeId FROM attributes WHERE isDeleted = 1 AND deleteId = ?" ,  [ deleteId ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseAttributes ( attributeIdsToErase ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  attachmentIdsToErase  =  sql . getColumn ( "SELECT attachmentId FROM attachments WHERE isDeleted = 1 AND deleteId = ?" ,  [ deleteId ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseAttachments ( attachmentIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseUnusedBlobs ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 22:11:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseDeletedNotesNow ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    eraseDeletedEntities ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 22:11:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseUnusedAttachmentsNow ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseScheduledAttachments ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// do a replace in str - all keys should be replaced by the corresponding values
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  replaceByMap ( str ,  mapObj )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  re  =  new  RegExp ( Object . keys ( mapObj ) . join ( "|" ) , "g" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  str . replace ( re ,  matched  =>  mapObj [ matched ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  duplicateSubtree ( origNoteId ,  newParentNoteId )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( origNoteId  ===  'root' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( 'Duplicating root is not possible' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-09 22:45:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    log . info ( ` Duplicating ' ${ origNoteId } ' subtree into ' ${ newParentNoteId } ' ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 22:35:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 22:02:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  origNote  =  becca . notes [ origNoteId ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // might be null if orig note is not in the target newParentNoteId
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 17:30:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  origBranch  =  origNote . getParentBranches ( ) . find ( branch  =>  branch . parentNoteId  ===  newParentNoteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  noteIdMapping  =  getNoteIdMapping ( origNote ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  res  =  duplicateSubtreeInner ( origNote ,  origBranch ,  newParentNoteId ,  noteIdMapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-23 19:44:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! res . note . title . endsWith ( '(dup)' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        res . note . title  +=  " (dup)" ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    res . note . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  duplicateSubtreeWithoutRoot ( origNoteId ,  newNoteId )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( origNoteId  ===  'root' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( 'Duplicating root is not possible' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-02 11:23:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  origNote  =  becca . getNote ( origNoteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  noteIdMapping  =  getNoteIdMapping ( origNote ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  childBranch  of  origNote . getChildBranches ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        duplicateSubtreeInner ( childBranch . getNote ( ) ,  childBranch ,  newNoteId ,  noteIdMapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  duplicateSubtreeInner ( origNote ,  origBranch ,  newParentNoteId ,  noteIdMapping )  {  
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( origNote . isProtected  &&  ! protectedSessionService . isProtectedSessionAvailable ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        throw  new  Error ( ` Cannot duplicate note ' ${ origNote . noteId } ' because it is protected and protected session is not available. Enter protected session and try again. ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-14 12:14:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  newNoteId  =  noteIdMapping [ origNote . noteId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    function  createDuplicatedBranch ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  new  BBranch ( { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            noteId :  newNoteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            parentNoteId :  newParentNoteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // here increasing just by 1 to make sure it's directly after original
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            notePosition :  origBranch  ?  origBranch . notePosition  +  1  :  null 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-14 12:14:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    function  createDuplicatedNote ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  newNote  =  new  BNote ( { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ... origNote , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            noteId :  newNoteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dateCreated :  dateUtils . localNowDateTime ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            utcDateCreated :  dateUtils . utcNowDateTime ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) . save ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-18 22:20:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        let  content  =  origNote . getContent ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 23:01:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( [ 'text' ,  'relationMap' ,  'search' ] . includes ( origNote . type ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // fix links in the content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content  =  replaceByMap ( content ,  noteIdMapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        newNote . setContent ( content ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  attribute  of  origNote . getOwnedAttributes ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-03 13:52:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  attr  =  new  BAttribute ( { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                ... attribute , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                attributeId :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                noteId :  newNote . noteId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // if relation points to within the duplicated tree then replace the target to the duplicated note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // if it points outside of duplicated tree then keep the original target
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( attr . type  ===  'relation'  &&  attr . value  in  noteIdMapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                attr . value  =  noteIdMapping [ attr . value ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-09 22:45:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // the relation targets may not be created yet, the mapping is pre-generated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            attr . save ( { skipValidation :  true } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  childBranch  of  origNote . getChildBranches ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            duplicateSubtreeInner ( childBranch . getNote ( ) ,  childBranch ,  newNote . noteId ,  noteIdMapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-22 23:36:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  newNote ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  existingNote  =  becca . notes [ newNoteId ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-02 23:26:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( existingNote  &&  existingNote . title  !==  undefined )  {  // checking that it's not just note's skeleton created because of Branch above
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // note has multiple clones and was already created from another placement in the tree
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // so a branch is all we need for this clone
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note :  existingNote , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            branch :  createDuplicatedBranch ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // order here is important, note needs to be created first to not mess up the becca
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            note :  createDuplicatedNote ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            branch :  createDuplicatedBranch ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-19 12:36:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  getNoteIdMapping ( origNote )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  noteIdMapping  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // pregenerate new noteIds since we'll need to fix relation references even for not yet created notes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( const  origNoteId  of  origNote . getDescendantNoteIds ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        noteIdMapping [ origNoteId ]  =  utils . newEntityId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-14 12:14:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  noteIdMapping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  eraseScheduledAttachments ( eraseUnusedImageAttachmentsAfterSeconds  =  null )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( eraseUnusedImageAttachmentsAfterSeconds  ===  null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        eraseUnusedImageAttachmentsAfterSeconds  =  optionService . getOptionInt ( 'eraseUnusedImageAttachmentsAfterSeconds' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  cutOffDate  =  dateUtils . utcDateTimeStr ( new  Date ( Date . now ( )  -  ( eraseUnusedImageAttachmentsAfterSeconds  *  1000 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  attachmentIdsToErase  =  sql . getColumn ( 'SELECT attachmentId FROM attachments WHERE utcDateScheduledForErasureSince < ?' ,  [ cutOffDate ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    eraseAttachments ( attachmentIdsToErase ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 21:42:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								sqlInit . dbReady . then ( ( )  =>  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // first cleanup kickoff 5 minutes after startup
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setTimeout ( cls . wrap ( ( )  =>  eraseDeletedEntities ( ) ) ,  5  *  60  *  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setTimeout ( cls . wrap ( ( )  =>  eraseScheduledAttachments ( ) ) ,  6  *  60  *  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-01 10:23:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 13:47:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setInterval ( cls . wrap ( ( )  =>  eraseDeletedEntities ( ) ) ,  4  *  3600  *  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 00:19:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    setInterval ( cls . wrap ( ( )  =>  eraseScheduledAttachments ( ) ) ,  3600  *  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 21:42:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ) ;  
						 
					
						
							
								
									
										
										
										
											2018-11-01 10:23:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-05 10:41:54 -05:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								module . exports  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    createNewNote , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-16 12:28:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    createNewNoteWithTarget , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-24 09:19:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    updateNoteData , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 13:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    undeleteNote , 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-01 20:35:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    protectNoteRecursively , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:06:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    duplicateSubtree , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-19 14:29:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    duplicateSubtreeWithoutRoot , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 23:31:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    getUndeletedParentBranchIds , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-06 22:11:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    triggerNoteTitleChanged , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-16 14:38:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    eraseDeletedNotesNow , 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-24 21:22:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    eraseUnusedAttachmentsNow , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-08 21:04:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    eraseNotesWithDeleteId , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-02 17:25:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    saveNoteRevisionIfNeeded , 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-26 20:32:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    downloadImages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    asyncPostProcessContent 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-03 15:49:27 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;