I forgot to mention that the last line needs to calculate the length of the vector:
length( dot((WorldPosition - FlashLightPosition), FlashLightDirection) * FlashLightDirection )
Once I fixed that I tested it out and it works perfectly.
Then to make this work for visibility you can change the ‘hardness’ of the spheremask and use it as an opacity mask. Keep in mind this won’t have shadows from the environment and if you need those, you will likely need a much more elaborate features like a scene capture just to get the scene depth as seen from the light. Or you could try to raytrace the scene depth for intersection.