@@ -6,6 +6,8 @@ import { Ctx } from '../processor'
66import * as v63 from '../types/v63'
77import { validateString } from "./nodes"
88
9+ import * as ipaddr from 'ipaddr.js' ;
10+
911export class FarmWithIPs {
1012 constructor ( farmID : number , ips : PublicIp [ ] ) {
1113 this . farmID = farmID
@@ -56,6 +58,10 @@ export async function farmStored(
5658 await ctx . store . save < Farm > ( newFarm )
5759
5860 const ipPromises = farmStoredEventParsed . publicIps . map ( ip => {
61+ if ( ! checkIPs ( ctx , ip . ip . toString ( ) , ip . gateway . toString ( ) ) ) {
62+ return Promise . resolve ( )
63+ }
64+
5965 const newIP = new PublicIp ( )
6066
6167 newIP . id = item . event . id
@@ -67,13 +73,56 @@ export async function farmStored(
6773 newIP . farm = newFarm
6874
6975 newFarm . publicIPs ?. push ( newIP )
70-
76+ ctx . log . debug ( { eventName : item . name , ip : newIP . ip } , `Public IP: ${ newIP . ip } added with farm id: ${ newFarm . farmID } ` ) ;
7177 return ctx . store . save < PublicIp > ( newIP )
7278 } )
7379 await Promise . all ( ipPromises )
7480 await ctx . store . save < Farm > ( newFarm )
7581}
7682
83+ function checkIPs ( ctx : Ctx , ipv4_a : string , ipv4_b : string ) : boolean {
84+ try {
85+ // Check if both IP addresses are valid
86+ if ( ! ipaddr . isValidCIDR ( ipv4_a ) || ! ipaddr . isValid ( ipv4_b ) ) {
87+ ctx . log . warn ( `One or both IP addresses are invalid. Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
88+ return false ;
89+ }
90+ // Parse the IP addresses
91+ const ip_a = ipaddr . parseCIDR ( ipv4_a ) ;
92+ const ip_b = ipaddr . parse ( ipv4_b ) ;
93+
94+ // check if both IP addresses are the same
95+ if ( ip_a [ 0 ] == ip_b ) {
96+ ctx . log . warn ( `The IP addresses are the same. Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
97+ return false ;
98+ }
99+
100+ // Check if both IP addresses are public
101+ if ( ip_a [ 0 ] . range ( ) == 'private' || ip_b . range ( ) == 'private' ) {
102+ ctx . log . warn ( `One or both IP addresses are not public. Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
103+ return false ;
104+ }
105+
106+ // Check if both IP addresses are unicast addresses
107+ if ( ip_a [ 0 ] . range ( ) !== 'unicast' || ip_b . range ( ) !== 'unicast' ) {
108+ ctx . log . warn ( `One or both IP addresses are not unicast addresses. Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
109+ return false ;
110+ }
111+
112+
113+ // Check if the gateway is in the same subnet as the host
114+ if ( ! ip_b . match ( ip_a ) ) {
115+ ctx . log . warn ( `The gateway is not in the same subnet as the host. Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
116+ return false ;
117+ }
118+
119+ return true ;
120+ } catch ( error : any ) {
121+ ctx . log . error ( `An error occurred: ${ error . message } . Public IP: ${ ipv4_a } , Gateway: ${ ipv4_b } ` ) ;
122+ return false ;
123+ }
124+ }
125+
77126export async function farmUpdated (
78127 ctx : Ctx ,
79128 item : EventItem < 'TfgridModule.FarmUpdated' , { event : { args : true } } >
@@ -122,8 +171,10 @@ export async function farmUpdated(
122171 savedFarm . certification = certification
123172
124173 let eventPublicIPs = farmUpdatedEventParsed . publicIps
125-
126- await farmUpdatedEventParsed . publicIps . forEach ( async ip => {
174+ farmUpdatedEventParsed . publicIps . forEach ( async ip => {
175+ if ( ! checkIPs ( ctx , ip . ip . toString ( ) , ip . gateway . toString ( ) ) ) {
176+ return
177+ }
127178 if ( ip . ip . toString ( ) . indexOf ( '\x00' ) >= 0 ) {
128179 return
129180 }
@@ -132,20 +183,24 @@ export async function farmUpdated(
132183 if ( savedIP ) {
133184 savedIP . ip = validateString ( ctx , ip . ip . toString ( ) ) // not effective, but for since we already check for \x00
134185 savedIP . gateway = validateString ( ctx , ip . gateway . toString ( ) )
186+ if ( savedIP . farm . id !== savedFarm . id ) {
187+ ctx . log . error ( { eventName : item . name , ip : ip . ip . toString ( ) } , `PublicIP: ${ ip . ip . toString ( ) } already exists on farm: ${ savedIP . farm . farmID } , skiped adding it to farm with ID: ${ savedFarm . farmID } ` ) ;
188+ }
135189 await ctx . store . save < PublicIp > ( savedIP )
136190 } else {
191+
137192 const newIP = new PublicIp ( )
138193 newIP . id = item . event . id
139194 newIP . ip = validateString ( ctx , ip . ip . toString ( ) )
140195 newIP . gateway = validateString ( ctx , ip . gateway . toString ( ) )
141196 newIP . contractId = ip . contractId
142197 newIP . farm = savedFarm
143-
144198 await ctx . store . save < PublicIp > ( newIP )
145199 if ( ! savedFarm . publicIPs ) {
146200 savedFarm . publicIPs = [ ]
147201 }
148202 savedFarm . publicIPs . push ( newIP )
203+ ctx . log . debug ( { eventName : item . name , ip : ip . ip . toString ( ) } , `PublicIP: ${ ip . ip . toString ( ) } added with farm id: ${ savedFarm . farmID } ` ) ;
149204 }
150205 } )
151206
@@ -156,14 +211,19 @@ export async function farmUpdated(
156211 if ( eventPublicIPs . filter ( eventIp => validateString ( ctx , eventIp . ip . toString ( ) ) === ip . ip ) . length === 0 ) {
157212 // IP got removed from farm
158213 await ctx . store . remove < PublicIp > ( ip )
214+ // remove ip from savedFarm.publicIPs
215+ // savedFarm.publicIPs = savedFarm.publicIPs.filter(savedIP => savedIP.id !== ip.id)
216+ // TODO: check if we need this code above? or Cascade delete involving here?
217+ ctx . log . debug ( { eventName : item . name , ip : ip . ip . toString ( ) } , `PublicIP: ${ ip . ip . toString ( ) } in farm: ${ savedFarm . farmID } removed from publicIPs` ) ;
159218 }
160219 } )
161220
162221 let farm = item . event . args as Farm
163222 if ( farm . dedicatedFarm ) {
164223 savedFarm . dedicatedFarm = farm . dedicatedFarm
165- await ctx . store . save < Farm > ( savedFarm )
166224 }
225+ await ctx . store . save < Farm > ( savedFarm )
226+
167227}
168228
169229export async function farmDeleted (
@@ -176,6 +236,7 @@ export async function farmDeleted(
176236
177237 if ( savedFarm ) {
178238 await ctx . store . remove ( savedFarm )
239+ ctx . log . debug ( { eventName : item . name , farmID : savedFarm . farmID } , `Farm: ${ savedFarm . farmID } removed from storage` ) ;
179240 }
180241}
181242
0 commit comments