namespace JiDangJia.Server;
// Release outputs are disposable. Account databases and encryption keys are not.
public static class PrivateStorage
{
public static string DefaultDirectory=>Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"JiDangJia",ServerProduct.DirectoryName);
public static string OutsideArtifacts(string path)
{
var full=Path.GetFullPath(path);
void Check(string value)
{
if(value.Split([Path.DirectorySeparatorChar,Path.AltDirectorySeparatorChar]).Any(part=>part.Equals("artifacts",StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException("账户数据、密钥和密码禁止存放在 artifacts 下。请停止服务,将整个原数据目录迁移到项目外,并通过 DataDirectory 指定该目录。");
}
Check(full);
if(File.Exists(full)&&new FileInfo(full) is { LinkTarget:not null } link&&link.ResolveLinkTarget(true) is { } fileTarget)Check(fileTarget.FullName);
// Also reject an external alias that resolves back into release outputs.
for(var entry=new DirectoryInfo(full);entry is not null;entry=entry.Parent)
if(entry.Exists&&entry.LinkTarget is not null&&entry.ResolveLinkTarget(true) is { } target)Check(target.FullName);
return full;
}
}
namespace JiDangJia.Server;
// Release outputs are disposable. Account databases and encryption keys are not.
public static class PrivateStorage
{
public static string DefaultDirectory=>Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"JiDangJia",ServerProduct.DirectoryName);
public static string OutsideArtifacts(string path)
{
var full=Path.GetFullPath(path);
void Check(string value)
{
if(value.Split([Path.DirectorySeparatorChar,Path.AltDirectorySeparatorChar]).Any(part=>part.Equals("artifacts",StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException("账户数据、密钥和密码禁止存放在 artifacts 下。请停止服务,将整个原数据目录迁移到项目外,并通过 DataDirectory 指定该目录。");
}
Check(full);
if(File.Exists(full)&&new FileInfo(full) is { LinkTarget:not null } link&&link.ResolveLinkTarget(true) is { } fileTarget)Check(fileTarget.FullName);
// Also reject an external alias that resolves back into release outputs.
for(var entry=new DirectoryInfo(full);entry is not null;entry=entry.Parent)
if(entry.Exists&&entry.LinkTarget is not null&&entry.ResolveLinkTarget(true) is { } target)Check(target.FullName);
return full;
}
}