This commit is contained in:
snltty
2025-07-01 01:13:22 +08:00
parent 4c88a585c9
commit d859293fc7
68 changed files with 1240 additions and 710 deletions

View File

@@ -83,6 +83,7 @@ jobs:
dotnet pack ./src/linker.messenger.updater -c release dotnet pack ./src/linker.messenger.updater -c release
dotnet pack ./src/linker.messenger.firewall -c release dotnet pack ./src/linker.messenger.firewall -c release
dotnet pack ./src/linker.messenger.wakeup -c release dotnet pack ./src/linker.messenger.wakeup -c release
dotnet pack ./src/linker.messenger.wlist -c release
dotnet pack ./src/linker.tun -c release dotnet pack ./src/linker.tun -c release
dotnet pack ./src/linker.snat -c release dotnet pack ./src/linker.snat -c release
dotnet pack ./src/linker.tunnel -c release dotnet pack ./src/linker.tunnel -c release
@@ -117,6 +118,7 @@ jobs:
dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.firewall/bin/release/linker.messenger.firewall.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.firewall/bin/release/linker.messenger.firewall.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.wakeup/bin/release/linker.messenger.wakeup.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.wakeup/bin/release/linker.messenger.wakeup.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.wlist/bin/release/linker.messenger.wlist.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tun/bin/release/linker.tun.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.tun/bin/release/linker.tun.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.snat/bin/release/linker.snat.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.snat/bin/release/linker.snat.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.1.8.5.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols

View File

@@ -95,6 +95,7 @@
- 浅浅 - 浅浅
- 仰望 * 2 - 仰望 * 2
- 李氏の天下 - 李氏の天下
- 小猪
</div> </div>
</details> </details>

View File

@@ -71,7 +71,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.wakeup", "
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.cdkey", "src\linker.messenger.cdkey\linker.messenger.cdkey.csproj", "{B03C0E46-1C0F-46C2-B026-8F02F5C643D4}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.cdkey", "src\linker.messenger.cdkey\linker.messenger.cdkey.csproj", "{B03C0E46-1C0F-46C2-B026-8F02F5C643D4}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.messenger.rapp", "src\linker.messenger.rapp\linker.messenger.rapp.csproj", "{B895C1DC-9C75-407D-98CE-5DB873F32278}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.messenger.rapp", "src\linker.messenger.rapp\linker.messenger.rapp.csproj", "{B895C1DC-9C75-407D-98CE-5DB873F32278}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.messenger.wlist", "src\linker.messenger.wlist\linker.messenger.wlist.csproj", "{26550C65-0960-4BA3-9F83-BAC90DE9AA57}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -509,6 +511,18 @@ Global
{B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x64.Build.0 = Release|Any CPU {B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x64.Build.0 = Release|Any CPU
{B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x86.ActiveCfg = Release|Any CPU {B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x86.ActiveCfg = Release|Any CPU
{B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x86.Build.0 = Release|Any CPU {B895C1DC-9C75-407D-98CE-5DB873F32278}.Release|x86.Build.0 = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|x64.ActiveCfg = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|x64.Build.0 = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|x86.ActiveCfg = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Debug|x86.Build.0 = Debug|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|Any CPU.Build.0 = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|x64.ActiveCfg = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|x64.Build.0 = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|x86.ActiveCfg = Release|Any CPU
{26550C65-0960-4BA3-9F83-BAC90DE9AA57}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -17,6 +17,7 @@ sidebar_position: 96
- 浅浅 - 浅浅
- 仰望 * 2 - 仰望 * 2
- 李氏の天下 - 李氏の天下
- 小猪
</div> </div>
</details> </details>

View File

@@ -41,11 +41,11 @@ namespace linker.libs.extends
return str.Substring(start, maxLength); return str.Substring(start, maxLength);
} }
/// <summary> /// <summary>
/// md5 /// sha256
/// </summary> /// </summary>
/// <param name="input"></param> /// <param name="input"></param>
/// <returns></returns> /// <returns></returns>
public static string Md5(this string input) public static string Sha256(this string input)
{ {
byte[] data = SHA256.HashData(Encoding.Default.GetBytes(input)); byte[] data = SHA256.HashData(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new(); StringBuilder sBuilder = new();
@@ -55,6 +55,16 @@ namespace linker.libs.extends
} }
return sBuilder.ToString(); return sBuilder.ToString();
} }
public static string Md5(this string input)
{
byte[] data = MD5.HashData(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
#region utf8 #region utf8

View File

@@ -153,8 +153,8 @@ namespace linker.messenger.api
[AccessDisplay("修改所有验证参数")] [AccessDisplay("修改所有验证参数")]
ActionOther = 48, ActionOther = 48,
[AccessDisplay("中继白名单")] [AccessDisplay("白名单")]
User2Node = 49, WhiteList = 49,
} }
public sealed class AccessTextInfo public sealed class AccessTextInfo

View File

@@ -42,7 +42,7 @@ namespace linker.messenger.cdkey
var resp = await messengerSender.SendReply(new MessageRequestWrap var resp = await messengerSender.SendReply(new MessageRequestWrap
{ {
Connection = signInClientState.Connection, Connection = signInClientState.Connection,
MessengerId = (ushort)CdkeyMessengerIds.AccessCdkey, MessengerId = (ushort)CdkeyMessengerIds.CheckKey,
Payload = serializer.Serialize(cdkeyClientStore.SecretKey) Payload = serializer.Serialize(cdkeyClientStore.SecretKey)
}).ConfigureAwait(false); }).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);

View File

@@ -136,7 +136,7 @@ namespace linker.messenger.cdkey
} }
[MessengerId((ushort)CdkeyMessengerIds.AccessCdkey)] [MessengerId((ushort)CdkeyMessengerIds.CheckKey)]
public void AccessCdkey(IConnection connection) public void AccessCdkey(IConnection connection)
{ {
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span); string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);

View File

@@ -7,7 +7,7 @@
AddCdkey = 3501, AddCdkey = 3501,
PageCdkey = 3502, PageCdkey = 3502,
DelCdkey = 3503, DelCdkey = 3503,
AccessCdkey = 3504, CheckKey = 3504,
TestCdkey = 3505, TestCdkey = 3505,
ImportCdkey = 3506, ImportCdkey = 3506,

View File

@@ -23,6 +23,7 @@ using System.Text.Json;
using linker.messenger.firewall; using linker.messenger.firewall;
using linker.messenger.wakeup; using linker.messenger.wakeup;
using linker.messenger.cdkey; using linker.messenger.cdkey;
using linker.messenger.wlist;
namespace linker.messenger.entry namespace linker.messenger.entry
{ {
@@ -102,8 +103,10 @@ namespace linker.messenger.entry
.AddFirewallClient().AddFirewallServer() .AddFirewallClient().AddFirewallServer()
//唤醒 //唤醒
.AddWakeupClient().AddWakeupServer(); .AddWakeupClient().AddWakeupServer()
//白名单
.AddWhiteListClient().AddWhiteListServer();
} }
/// <summary> /// <summary>
@@ -186,7 +189,7 @@ namespace linker.messenger.entry
serviceProvider.UseWakeupServer(); serviceProvider.UseWakeupServer();
serviceProvider.UseAccessServer().UseDecenterServer().UsePcpServer() serviceProvider.UseAccessServer().UseDecenterServer().UsePcpServer()
.UseRelayServer().UseCdkeyServer() .UseRelayServer().UseCdkeyServer().UseWhiteListServer()
.UseSignInServer().UseSyncServer().UseTunnelServer().UseFlowServer(); .UseSignInServer().UseSyncServer().UseTunnelServer().UseFlowServer();
serviceProvider.UseListen(); serviceProvider.UseListen();
@@ -219,7 +222,7 @@ namespace linker.messenger.entry
serviceProvider.UseExRoute().UseAccessClient().UseDecenterClient().UsePcpClient() serviceProvider.UseExRoute().UseAccessClient().UseDecenterClient().UsePcpClient()
.UseRelayClient().UseCdkeyClient() .UseRelayClient().UseCdkeyClient().UseWhiteListClient()
.UseSyncClient().UseTunnelClient().UseFlowClient(); .UseSyncClient().UseTunnelClient().UseFlowClient();
serviceProvider.UseSignInClient(); serviceProvider.UseSignInClient();

View File

@@ -60,6 +60,7 @@
<ProjectReference Include="..\linker.messenger.tuntap\linker.messenger.tuntap.csproj" /> <ProjectReference Include="..\linker.messenger.tuntap\linker.messenger.tuntap.csproj" />
<ProjectReference Include="..\linker.messenger.updater\linker.messenger.updater.csproj" /> <ProjectReference Include="..\linker.messenger.updater\linker.messenger.updater.csproj" />
<ProjectReference Include="..\linker.messenger.wakeup\linker.messenger.wakeup.csproj" /> <ProjectReference Include="..\linker.messenger.wakeup\linker.messenger.wakeup.csproj" />
<ProjectReference Include="..\linker.messenger.wlist\linker.messenger.wlist.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" /> <ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -52,7 +52,7 @@ namespace linker.messenger.forward.proxy
SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(bytes, tempRemoteEP).ConfigureAwait(false); SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(bytes, tempRemoteEP).ConfigureAwait(false);
if(result.ReceivedBytes == 0) if(result.ReceivedBytes == 0)
{ {
break; continue;
} }
token.Proxy.SourceEP = result.RemoteEndPoint as IPEndPoint; token.Proxy.SourceEP = result.RemoteEndPoint as IPEndPoint;

View File

@@ -43,7 +43,7 @@ namespace linker.messenger.listen
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
LoggerHelper.Instance.Error($"udp server recv 0"); LoggerHelper.Instance.Error($"udp server recv 0");
break; continue;
} }
IPEndPoint ep = result.RemoteEndPoint as IPEndPoint; IPEndPoint ep = result.RemoteEndPoint as IPEndPoint;
try try

View File

@@ -127,75 +127,11 @@ namespace linker.messenger.relay
{ {
Connection = signInClientState.Connection, Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.CheckKey, MessengerId = (ushort)RelayMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content) Payload = serializer.Serialize(relayClientStore.Server.SecretKey)
}).ConfigureAwait(false); }).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
} }
/// <summary>
/// 添加用户到节点
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<bool> AddUser2Node(ApiControllerParamsInfo param)
{
RelayServerUser2NodeInfo info = param.Content.DeJson<RelayServerUser2NodeInfo>();
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.AddUser2Node,
Payload = serializer.Serialize(new RelayServerUser2NodeAddInfo
{
Data = info,
SecretKey = relayClientStore.Server.SecretKey
})
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
/// <summary>
/// 删除用户到节点
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<bool> DelUser2Node(ApiControllerParamsInfo param)
{
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.DelUser2Node,
Payload = serializer.Serialize(new RelayServerUser2NodeDelInfo
{
Id = int.Parse(param.Content),
SecretKey = relayClientStore.Server.SecretKey
})
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
/// <summary>
/// 用户到节点分页查询
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<RelayServerUser2NodePageResultInfo> PageUser2Node(ApiControllerParamsInfo param)
{
RelayServerUser2NodePageRequestInfo info = param.Content.DeJson<RelayServerUser2NodePageRequestInfo>();
info.SecretKey = relayClientStore.Server.SecretKey;
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.PageUser2Node,
Payload = serializer.Serialize(info)
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK)
{
return serializer.Deserialize<RelayServerUser2NodePageResultInfo>(resp.Data.Span);
}
return new RelayServerUser2NodePageResultInfo();
}
} }
public sealed class SyncInfo public sealed class SyncInfo

View File

@@ -46,6 +46,7 @@
<ProjectReference Include="..\linker.messenger.cdkey\linker.messenger.cdkey.csproj" /> <ProjectReference Include="..\linker.messenger.cdkey\linker.messenger.cdkey.csproj" />
<ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" /> <ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.messenger.sync\linker.messenger.sync.csproj" /> <ProjectReference Include="..\linker.messenger.sync\linker.messenger.sync.csproj" />
<ProjectReference Include="..\linker.messenger.wlist\linker.messenger.wlist.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" /> <ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
<ProjectReference Include="..\linker.tunnel\linker.tunnel.csproj" /> <ProjectReference Include="..\linker.tunnel\linker.tunnel.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -5,7 +5,6 @@ using linker.messenger.relay.client;
using linker.messenger.relay.server; using linker.messenger.relay.server;
using linker.messenger.signin; using linker.messenger.signin;
using linker.messenger.relay.server.validator; using linker.messenger.relay.server.validator;
using linker.messenger.cdkey;
namespace linker.messenger.relay.messenger namespace linker.messenger.relay.messenger
{ {
@@ -48,9 +47,8 @@ namespace linker.messenger.relay.messenger
private readonly ISerializer serializer; private readonly ISerializer serializer;
private readonly IRelayServerStore relayServerStore; private readonly IRelayServerStore relayServerStore;
private readonly RelayServerNodeTransfer relayServerNodeTransfer; private readonly RelayServerNodeTransfer relayServerNodeTransfer;
private readonly IRelayServerUser2NodeStore relayServerUser2NodeStore;
public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, IRelayServerStore relayServerStore, RelayServerNodeTransfer relayServerNodeTransfer, IRelayServerUser2NodeStore relayServerUser2NodeStore) public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, IRelayServerStore relayServerStore, RelayServerNodeTransfer relayServerNodeTransfer)
{ {
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.signCaching = signCaching; this.signCaching = signCaching;
@@ -59,7 +57,6 @@ namespace linker.messenger.relay.messenger
this.serializer = serializer; this.serializer = serializer;
this.relayServerStore = relayServerStore; this.relayServerStore = relayServerStore;
this.relayServerNodeTransfer = relayServerNodeTransfer; this.relayServerNodeTransfer = relayServerNodeTransfer;
this.relayServerUser2NodeStore = relayServerUser2NodeStore;
} }
/// <summary> /// <summary>
@@ -356,78 +353,5 @@ namespace linker.messenger.relay.messenger
connection.Write(relayServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray); connection.Write(relayServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
} }
/// <summary>
/// 添加CDKEY
/// </summary>
/// <param name="connection"></param>
[MessengerId((ushort)RelayMessengerIds.AddUser2Node)]
public async Task AddUser2Node(IConnection connection)
{
RelayServerUser2NodeAddInfo info = serializer.Deserialize<RelayServerUser2NodeAddInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(Helper.FalseArray);
return;
}
if (relayServerStore.ValidateSecretKey(info.SecretKey) == false)
{
connection.Write(Helper.FalseArray);
return;
}
await relayServerUser2NodeStore.Add(info.Data).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
}
/// <summary>
/// 删除Cdkey
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)RelayMessengerIds.DelUser2Node)]
public async Task DelUser2Node(IConnection connection)
{
RelayServerUser2NodeDelInfo info = serializer.Deserialize<RelayServerUser2NodeDelInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(Helper.FalseArray);
return;
}
if (relayServerStore.ValidateSecretKey(info.SecretKey) == false)
{
connection.Write(Helper.FalseArray);
return;
}
await relayServerUser2NodeStore.Del(info.Id).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
}
/// <summary>
/// 查询CDKEY
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)RelayMessengerIds.PageUser2Node)]
public async Task PageUser2Node(IConnection connection)
{
RelayServerUser2NodePageRequestInfo info = serializer.Deserialize<RelayServerUser2NodePageRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(serializer.Serialize(new RelayServerUser2NodePageResultInfo { }));
return;
}
if (relayServerStore.ValidateSecretKey(info.SecretKey) == false && string.IsNullOrWhiteSpace(info.UserId))
{
connection.Write(serializer.Serialize(new RelayServerUser2NodePageResultInfo { }));
return;
}
var page = await relayServerUser2NodeStore.Page(info).ConfigureAwait(false);
connection.Write(serializer.Serialize(page));
}
} }
} }

View File

@@ -31,11 +31,7 @@
CheckKey = 2123, CheckKey = 2123,
AddUser2Node = 2124, NodeGetCache186 = 2124,
DelUser2Node = 2125,
PageUser2Node = 2126,
NodeGetCache186 = 2127,
Max = 2199 Max = 2199
} }

View File

@@ -1,47 +0,0 @@
namespace linker.messenger.relay.server
{
public interface IRelayServerUser2NodeStore
{
public Task<RelayServerUser2NodePageResultInfo> Page(RelayServerUser2NodePageRequestInfo request);
public Task<bool> Add(RelayServerUser2NodeInfo info);
public Task<bool> Del(int id);
public Task<List<string>> Get(string userid);
}
public sealed partial class RelayServerUser2NodeDelInfo
{
public string SecretKey { get; set; }
public int Id { get; set; }
}
public sealed partial class RelayServerUser2NodeAddInfo
{
public string SecretKey { get; set; }
public RelayServerUser2NodeInfo Data { get; set; }
}
public sealed partial class RelayServerUser2NodePageRequestInfo
{
public int Page { get; set; }
public int Size { get; set; }
public string UserId { get; set; }
public string Name { get; set; }
public string Remark { get; set; }
public string SecretKey { get; set; }
}
public sealed partial class RelayServerUser2NodePageResultInfo
{
public int Page { get; set; }
public int Size { get; set; }
public int Count { get; set; }
public List<RelayServerUser2NodeInfo> List { get; set; }
}
public sealed partial class RelayServerUser2NodeInfo
{
public int Id { get; set; }
public string UserId { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Remark { get; set; } = string.Empty;
public DateTime AddTime { get; set; } = DateTime.Now;
public string[] Nodes { get; set; } = [];
}
}

View File

@@ -4,6 +4,7 @@ using linker.libs.winapis;
using linker.messenger.cdkey; using linker.messenger.cdkey;
using linker.messenger.relay.messenger; using linker.messenger.relay.messenger;
using linker.messenger.relay.server.caching; using linker.messenger.relay.server.caching;
using linker.messenger.wlist;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
@@ -25,17 +26,17 @@ namespace linker.messenger.relay.server
private readonly IRelayServerMasterStore relayServerMasterStore; private readonly IRelayServerMasterStore relayServerMasterStore;
private readonly ICdkeyServerStore relayServerCdkeyStore; private readonly ICdkeyServerStore relayServerCdkeyStore;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly IRelayServerUser2NodeStore relayServerUser2NodeStore; private readonly IWhiteListServerStore whiteListServerStore;
private readonly ICdkeyServerStore cdkeyServerStore; private readonly ICdkeyServerStore cdkeyServerStore;
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, ISerializer serializer, IRelayServerMasterStore relayServerMasterStore, ICdkeyServerStore relayServerCdkeyStore, IMessengerSender messengerSender, IRelayServerUser2NodeStore relayServerUser2NodeStore, ICdkeyServerStore cdkeyServerStore) public RelayServerMasterTransfer(IRelayServerCaching relayCaching, ISerializer serializer, IRelayServerMasterStore relayServerMasterStore, ICdkeyServerStore relayServerCdkeyStore, IMessengerSender messengerSender, IWhiteListServerStore whiteListServerStore, ICdkeyServerStore cdkeyServerStore)
{ {
this.relayCaching = relayCaching; this.relayCaching = relayCaching;
this.serializer = serializer; this.serializer = serializer;
this.relayServerMasterStore = relayServerMasterStore; this.relayServerMasterStore = relayServerMasterStore;
this.relayServerCdkeyStore = relayServerCdkeyStore; this.relayServerCdkeyStore = relayServerCdkeyStore;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.relayServerUser2NodeStore = relayServerUser2NodeStore; this.whiteListServerStore = whiteListServerStore;
this.cdkeyServerStore = cdkeyServerStore; this.cdkeyServerStore = cdkeyServerStore;
TrafficTask(); TrafficTask();
} }
@@ -67,7 +68,7 @@ namespace linker.messenger.relay.server
{ {
if (relayCaching.TryGetValue(key, out RelayCacheInfo value)) if (relayCaching.TryGetValue(key, out RelayCacheInfo value))
{ {
value.Validated = value.Validated || (await relayServerUser2NodeStore.Get(value.UserId)).Contains(nodeid); value.Validated = value.Validated || (await whiteListServerStore.Get("Relay",value.UserId)).Contains(nodeid);
value.Cdkey = value.UseCdkey value.Cdkey = value.UseCdkey
? (await cdkeyServerStore.GetAvailable(value.UserId, "Relay").ConfigureAwait(false)).Select(c => new CdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList() ? (await cdkeyServerStore.GetAvailable(value.UserId, "Relay").ConfigureAwait(false)).Select(c => new CdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList()
: []; : [];
@@ -127,7 +128,7 @@ namespace linker.messenger.relay.server
/// <returns></returns> /// <returns></returns>
public async Task<List<RelayServerNodeReportInfo170>> GetNodes(bool validated, string userid) public async Task<List<RelayServerNodeReportInfo170>> GetNodes(bool validated, string userid)
{ {
var nodes = await relayServerUser2NodeStore.Get(userid); var nodes = await whiteListServerStore.Get("Relay",userid);
var result = reports.Values var result = reports.Values
.Where(c => Environment.TickCount64 - c.LastTicks < 15000) .Where(c => Environment.TickCount64 - c.LastTicks < 15000)

View File

@@ -394,7 +394,7 @@ namespace linker.messenger.relay.server
byte[] bytes = ArrayPool<byte>.Shared.Rent(1024); byte[] bytes = ArrayPool<byte>.Shared.Rent(1024);
try try
{ {
byte[] secretKeyBytes = secretKey.Md5().ToBytes(); byte[] secretKeyBytes = secretKey.Sha256().ToBytes();
bytes[0] = (byte)secretKeyBytes.Length; bytes[0] = (byte)secretKeyBytes.Length;
secretKeyBytes.AsSpan().CopyTo(bytes.AsSpan(1)); secretKeyBytes.AsSpan().CopyTo(bytes.AsSpan(1));

View File

@@ -46,7 +46,7 @@ namespace linker.messenger.relay.server
string key = buffer.AsMemory(0, length).GetString(); string key = buffer.AsMemory(0, length).GetString();
if (relayServerMasterStore.Master.SecretKey.Md5() == key) if (relayServerMasterStore.Master.SecretKey.Sha256() == key)
{ {
await messengerResolver.BeginReceiveServer(socket, Helper.EmptyArray).ConfigureAwait(false); await messengerResolver.BeginReceiveServer(socket, Helper.EmptyArray).ConfigureAwait(false);
} }

View File

@@ -73,11 +73,6 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateWrapInfoFormatter()); MemoryPackFormatterProvider.Register(new RelayServerNodeUpdateWrapInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerUser2NodeInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerUser2NodeAddInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerUser2NodeDelInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerUser2NodePageRequestInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerUser2NodePageResultInfoFormatter());
MemoryPackFormatterProvider.Register(new CdkeyInfoFormatter()); MemoryPackFormatterProvider.Register(new CdkeyInfoFormatter());
MemoryPackFormatterProvider.Register(new CdkeyStoreInfoFormatter()); MemoryPackFormatterProvider.Register(new CdkeyStoreInfoFormatter());
@@ -162,6 +157,13 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new WakeupSendInfoFormatter()); MemoryPackFormatterProvider.Register(new WakeupSendInfoFormatter());
MemoryPackFormatterProvider.Register(new WakeupSendForwardInfoFormatter()); MemoryPackFormatterProvider.Register(new WakeupSendForwardInfoFormatter());
MemoryPackFormatterProvider.Register(new WhiteListInfoFormatter());
MemoryPackFormatterProvider.Register(new WhiteListAddInfoFormatter());
MemoryPackFormatterProvider.Register(new WhiteListDelInfoFormatter());
MemoryPackFormatterProvider.Register(new WhiteListPageRequestInfoFormatter());
MemoryPackFormatterProvider.Register(new WhiteListPageResultInfoFormatter());
return serviceCollection; return serviceCollection;
} }
public static ServiceProvider UseSerializerMemoryPack(this ServiceProvider serviceProvider) public static ServiceProvider UseSerializerMemoryPack(this ServiceProvider serviceProvider)

View File

@@ -935,308 +935,4 @@ namespace linker.messenger.serializer.memorypack
} }
[MemoryPackable]
public readonly partial struct SerializableRelayServerUser2NodeInfo
{
[MemoryPackIgnore]
public readonly RelayServerUser2NodeInfo info;
[MemoryPackInclude]
int Id => info.Id;
[MemoryPackInclude]
string UserId => info.UserId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
string Remark => info.Remark;
[MemoryPackInclude]
DateTime AddTime => info.AddTime;
[MemoryPackInclude]
string[] Nodes => info.Nodes;
[MemoryPackConstructor]
SerializableRelayServerUser2NodeInfo(int id, string userid, string name, string remark, DateTime addTime, string[] nodes)
{
var info = new RelayServerUser2NodeInfo
{
Id = id,
UserId = userid,
AddTime = addTime,
Remark = remark,
Nodes = nodes,
Name = name
};
this.info = info;
}
public SerializableRelayServerUser2NodeInfo(RelayServerUser2NodeInfo info)
{
this.info = info;
}
}
public class RelayServerUser2NodeInfoFormatter : MemoryPackFormatter<RelayServerUser2NodeInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerUser2NodeInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerUser2NodeInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerUser2NodeInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerUser2NodeInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerUser2NodeAddInfo
{
[MemoryPackIgnore]
public readonly RelayServerUser2NodeAddInfo info;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude, MemoryPackAllowSerialize]
RelayServerUser2NodeInfo Data => info.Data;
[MemoryPackConstructor]
SerializableRelayServerUser2NodeAddInfo(string secretKey, RelayServerUser2NodeInfo data)
{
var info = new RelayServerUser2NodeAddInfo
{
SecretKey = secretKey,
Data = data
};
this.info = info;
}
public SerializableRelayServerUser2NodeAddInfo(RelayServerUser2NodeAddInfo info)
{
this.info = info;
}
}
public class RelayServerUser2NodeAddInfoFormatter : MemoryPackFormatter<RelayServerUser2NodeAddInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerUser2NodeAddInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerUser2NodeAddInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerUser2NodeAddInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerUser2NodeAddInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerUser2NodeDelInfo
{
[MemoryPackIgnore]
public readonly RelayServerUser2NodeDelInfo info;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude]
int Id => info.Id;
[MemoryPackConstructor]
SerializableRelayServerUser2NodeDelInfo(string secretKey, int id)
{
var info = new RelayServerUser2NodeDelInfo
{
SecretKey = secretKey,
Id = id
};
this.info = info;
}
public SerializableRelayServerUser2NodeDelInfo(RelayServerUser2NodeDelInfo info)
{
this.info = info;
}
}
public class RelayServerUser2NodeDelInfoFormatter : MemoryPackFormatter<RelayServerUser2NodeDelInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerUser2NodeDelInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerUser2NodeDelInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerUser2NodeDelInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerUser2NodeDelInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerUser2NodePageRequestInfo
{
[MemoryPackIgnore]
public readonly RelayServerUser2NodePageRequestInfo info;
[MemoryPackInclude]
int Page => info.Page;
[MemoryPackInclude]
int Size => info.Size;
[MemoryPackInclude]
string UserId => info.UserId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
string Remark => info.Remark;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackConstructor]
SerializableRelayServerUser2NodePageRequestInfo(int page, int size, string userid, string name, string remark, string secretKey)
{
var info = new RelayServerUser2NodePageRequestInfo
{
Size = size,
Page = page,
UserId = userid,
Remark = remark,
SecretKey = secretKey,
Name = name,
};
this.info = info;
}
public SerializableRelayServerUser2NodePageRequestInfo(RelayServerUser2NodePageRequestInfo info)
{
this.info = info;
}
}
public class RelayServerUser2NodePageRequestInfoFormatter : MemoryPackFormatter<RelayServerUser2NodePageRequestInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerUser2NodePageRequestInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerUser2NodePageRequestInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerUser2NodePageRequestInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerUser2NodePageRequestInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerUser2NodePageResultInfo
{
[MemoryPackIgnore]
public readonly RelayServerUser2NodePageResultInfo info;
[MemoryPackInclude]
int Page => info.Page;
[MemoryPackInclude]
int Size => info.Size;
[MemoryPackInclude]
int Count => info.Count;
[MemoryPackInclude]
List<RelayServerUser2NodeInfo> List => info.List;
[MemoryPackConstructor]
SerializableRelayServerUser2NodePageResultInfo(int page, int size, int count, List<RelayServerUser2NodeInfo> list)
{
var info = new RelayServerUser2NodePageResultInfo
{
Count = count,
List = list,
Size = size,
Page = page
};
this.info = info;
}
public SerializableRelayServerUser2NodePageResultInfo(RelayServerUser2NodePageResultInfo info)
{
this.info = info;
}
}
public class RelayServerUser2NodePageResultInfoFormatter : MemoryPackFormatter<RelayServerUser2NodePageResultInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerUser2NodePageResultInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerUser2NodePageResultInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerUser2NodePageResultInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableRelayServerUser2NodePageResultInfo>();
value = wrapped.info;
}
}
} }

View File

@@ -0,0 +1,317 @@
using linker.messenger.wlist;
using MemoryPack;
namespace linker.messenger.serializer.memorypack
{
[MemoryPackable]
public readonly partial struct SerializableWhiteListInfo
{
[MemoryPackIgnore]
public readonly WhiteListInfo info;
[MemoryPackInclude]
int Id => info.Id;
[MemoryPackInclude]
string Type => info.Type;
[MemoryPackInclude]
string UserId => info.UserId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
string Remark => info.Remark;
[MemoryPackInclude]
DateTime AddTime => info.AddTime;
[MemoryPackInclude]
string[] Nodes => info.Nodes;
[MemoryPackConstructor]
SerializableWhiteListInfo(int id, string type, string userid, string name, string remark, DateTime addTime, string[] nodes)
{
var info = new WhiteListInfo
{
Id = id,
Type = type,
UserId = userid,
AddTime = addTime,
Remark = remark,
Nodes = nodes,
Name = name
};
this.info = info;
}
public SerializableWhiteListInfo(WhiteListInfo info)
{
this.info = info;
}
}
public class WhiteListInfoFormatter : MemoryPackFormatter<WhiteListInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref WhiteListInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableWhiteListInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref WhiteListInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableWhiteListInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableWhiteListAddInfo
{
[MemoryPackIgnore]
public readonly WhiteListAddInfo info;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude, MemoryPackAllowSerialize]
WhiteListInfo Data => info.Data;
[MemoryPackConstructor]
SerializableWhiteListAddInfo(string secretKey, WhiteListInfo data)
{
var info = new WhiteListAddInfo
{
SecretKey = secretKey,
Data = data
};
this.info = info;
}
public SerializableWhiteListAddInfo(WhiteListAddInfo info)
{
this.info = info;
}
}
public class WhiteListAddInfoFormatter : MemoryPackFormatter<WhiteListAddInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref WhiteListAddInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableWhiteListAddInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref WhiteListAddInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableWhiteListAddInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableWhiteListDelInfo
{
[MemoryPackIgnore]
public readonly WhiteListDelInfo info;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackInclude]
int Id => info.Id;
[MemoryPackConstructor]
SerializableWhiteListDelInfo(string secretKey, int id)
{
var info = new WhiteListDelInfo
{
SecretKey = secretKey,
Id = id
};
this.info = info;
}
public SerializableWhiteListDelInfo(WhiteListDelInfo info)
{
this.info = info;
}
}
public class WhiteListDelInfoFormatter : MemoryPackFormatter<WhiteListDelInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref WhiteListDelInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableWhiteListDelInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref WhiteListDelInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableWhiteListDelInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableWhiteListPageRequestInfo
{
[MemoryPackIgnore]
public readonly WhiteListPageRequestInfo info;
[MemoryPackInclude]
int Page => info.Page;
[MemoryPackInclude]
int Size => info.Size;
[MemoryPackInclude]
string Type => info.Type;
[MemoryPackInclude]
string UserId => info.UserId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
string Remark => info.Remark;
[MemoryPackInclude]
string SecretKey => info.SecretKey;
[MemoryPackConstructor]
SerializableWhiteListPageRequestInfo(int page, int size, string type, string userid, string name, string remark, string secretKey)
{
var info = new WhiteListPageRequestInfo
{
Size = size,
Page = page,
Type = type,
UserId = userid,
Remark = remark,
SecretKey = secretKey,
Name = name,
};
this.info = info;
}
public SerializableWhiteListPageRequestInfo(WhiteListPageRequestInfo info)
{
this.info = info;
}
}
public class WhiteListPageRequestInfoFormatter : MemoryPackFormatter<WhiteListPageRequestInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref WhiteListPageRequestInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableWhiteListPageRequestInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref WhiteListPageRequestInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableWhiteListPageRequestInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableWhiteListPageResultInfo
{
[MemoryPackIgnore]
public readonly WhiteListPageResultInfo info;
[MemoryPackInclude]
int Page => info.Page;
[MemoryPackInclude]
int Size => info.Size;
[MemoryPackInclude]
int Count => info.Count;
[MemoryPackInclude]
List<WhiteListInfo> List => info.List;
[MemoryPackConstructor]
SerializableWhiteListPageResultInfo(int page, int size, int count, List<WhiteListInfo> list)
{
var info = new WhiteListPageResultInfo
{
Count = count,
List = list,
Size = size,
Page = page
};
this.info = info;
}
public SerializableWhiteListPageResultInfo(WhiteListPageResultInfo info)
{
this.info = info;
}
}
public class WhiteListPageResultInfoFormatter : MemoryPackFormatter<WhiteListPageResultInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref WhiteListPageResultInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableWhiteListPageResultInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref WhiteListPageResultInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableWhiteListPageResultInfo>();
value = wrapped.info;
}
}
}

View File

@@ -213,7 +213,7 @@ namespace linker.messenger.sforward.client
{ {
Connection = signInClientState.Connection, Connection = signInClientState.Connection,
MessengerId = (ushort)SForwardMessengerIds.CheckKey, MessengerId = (ushort)SForwardMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content) Payload = serializer.Serialize(sForwardClientStore.SecretKey)
}).ConfigureAwait(false); }).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray); return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
} }

View File

@@ -55,7 +55,7 @@ namespace linker.plugins.sforward.proxy
SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(buffer, tempRemoteEP).ConfigureAwait(false); SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(buffer, tempRemoteEP).ConfigureAwait(false);
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
break; continue;
} }
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
@@ -202,8 +202,7 @@ namespace linker.plugins.sforward.proxy
SocketReceiveFromResult result = await serverUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false); SocketReceiveFromResult result = await serverUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false);
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
cache.Clear(); continue;
break;
} }
cache.LastTicks.Update(); cache.LastTicks.Update();
@@ -246,8 +245,7 @@ namespace linker.plugins.sforward.proxy
SocketReceiveFromResult result = await serviceUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false); SocketReceiveFromResult result = await serviceUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false);
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
cache.Clear(); continue;
break;
} }
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
AddReceive(portStr, string.Empty, memory.Length); AddReceive(portStr, string.Empty, memory.Length);

View File

@@ -46,7 +46,7 @@ namespace linker.messenger.socks5
try try
{ {
SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(bytes, tempRemoteEP).ConfigureAwait(false); SocketReceiveFromResult result = await token.SourceSocket.ReceiveFromAsync(bytes, tempRemoteEP).ConfigureAwait(false);
if (result.ReceivedBytes == 0) break; if (result.ReceivedBytes == 0) continue;
token.Proxy.SourceEP = result.RemoteEndPoint as IPEndPoint; token.Proxy.SourceEP = result.RemoteEndPoint as IPEndPoint;
token.Proxy.Data = bytes.AsMemory(0, result.ReceivedBytes); token.Proxy.Data = bytes.AsMemory(0, result.ReceivedBytes);

View File

@@ -69,6 +69,8 @@ namespace linker.messenger.store.file
{ {
config.Data.Client.SForward.SecretKey = info.Client.SForwardSecretKey; config.Data.Client.SForward.SecretKey = info.Client.SForwardSecretKey;
config.Data.Client.Updater.SecretKey = info.Client.UpdaterSecretKey; config.Data.Client.Updater.SecretKey = info.Client.UpdaterSecretKey;
config.Data.Client.Cdkey.SecretKey = info.Client.CdkeySecretKey;
config.Data.Client.WhiteList.SecretKey = info.Client.WhiteListSecretKey;
foreach (var item in config.Data.Client.Relay.Servers) foreach (var item in config.Data.Client.Relay.Servers)
{ {
item.SecretKey = info.Client.RelaySecretKey; item.SecretKey = info.Client.RelaySecretKey;
@@ -93,6 +95,8 @@ namespace linker.messenger.store.file
config.Data.Server.SForward.TunnelPortRange = info.Server.SForward.TunnelPortRange; config.Data.Server.SForward.TunnelPortRange = info.Server.SForward.TunnelPortRange;
config.Data.Server.Updater.SecretKey = info.Server.Updater.SecretKey; config.Data.Server.Updater.SecretKey = info.Server.Updater.SecretKey;
config.Data.Server.Cdkey.SecretKey = info.Server.Cdkey.SecretKey;
config.Data.Server.WhiteList.SecretKey = info.Server.WhiteList.SecretKey;
} }
config.Data.Common.Modes = info.Common.Modes; config.Data.Common.Modes = info.Common.Modes;
@@ -291,10 +295,15 @@ namespace linker.messenger.store.file
if (configExportInfo.Updater) client.Updater = new linker.messenger.updater.UpdaterConfigClientInfo { SecretKey = client.Updater.SecretKey, Sync2Server = client.Updater.Sync2Server }; if (configExportInfo.Updater) client.Updater = new linker.messenger.updater.UpdaterConfigClientInfo { SecretKey = client.Updater.SecretKey, Sync2Server = client.Updater.Sync2Server };
else client.Updater = new linker.messenger.updater.UpdaterConfigClientInfo { }; else client.Updater = new linker.messenger.updater.UpdaterConfigClientInfo { };
if (configExportInfo.Tunnel) client.Tunnel = new TunnelConfigClientInfo { Transports = client.Tunnel.Transports }; if (configExportInfo.Tunnel) client.Tunnel = new TunnelConfigClientInfo { Transports = client.Tunnel.Transports };
else client.Tunnel = new TunnelConfigClientInfo { Transports = new List<linker.tunnel.transport.TunnelTransportItemInfo>() }; else client.Tunnel = new TunnelConfigClientInfo { Transports = new List<linker.tunnel.transport.TunnelTransportItemInfo>() };
if (configExportInfo.Cdkey) client.Cdkey = new linker.messenger.cdkey.CdkeyConfigInfo { SecretKey = client.Cdkey.SecretKey };
else client.Cdkey = new linker.messenger.cdkey.CdkeyConfigInfo { };
if (configExportInfo.WhiteList) client.WhiteList = new linker.messenger.wlist.WhiteListConfigInfo { SecretKey = client.WhiteList.SecretKey };
else client.WhiteList = new linker.messenger.wlist.WhiteListConfigInfo { };
ConfigCommonInfo common = config.Data.Common.ToJson().DeJson<ConfigCommonInfo>(); ConfigCommonInfo common = config.Data.Common.ToJson().DeJson<ConfigCommonInfo>();
common.Install = true; common.Install = true;
common.Modes = ["client"]; common.Modes = ["client"];
@@ -311,6 +320,8 @@ namespace linker.messenger.store.file
client.Updater, client.Updater,
Relay = new { Servers = new RelayServerInfo[] { client.Relay.Servers[0] } }, Relay = new { Servers = new RelayServerInfo[] { client.Relay.Servers[0] } },
client.Tunnel, client.Tunnel,
client.Cdkey,
client.WhiteList,
}, common, new { Install = true, Modes = new string[] { "client" } }); }, common, new { Install = true, Modes = new string[] { "client" } });
} }
@@ -350,6 +361,8 @@ namespace linker.messenger.store.file
public string SForwardSecretKey { get; set; } public string SForwardSecretKey { get; set; }
public string RelaySecretKey { get; set; } public string RelaySecretKey { get; set; }
public string UpdaterSecretKey { get; set; } public string UpdaterSecretKey { get; set; }
public string CdkeySecretKey { get; set; }
public string WhiteListSecretKey { get; set; }
} }
public sealed class ConfigInstallServerInfo public sealed class ConfigInstallServerInfo
{ {
@@ -357,6 +370,8 @@ namespace linker.messenger.store.file
public ConfigInstallServerRelayInfo Relay { get; set; } public ConfigInstallServerRelayInfo Relay { get; set; }
public ConfigInstallServerSForwardInfo SForward { get; set; } public ConfigInstallServerSForwardInfo SForward { get; set; }
public ConfigInstallServerUpdaterInfo Updater { get; set; } public ConfigInstallServerUpdaterInfo Updater { get; set; }
public ConfigInstallServerCdkeyInfo Cdkey { get; set; }
public ConfigInstallServerWhiteListInfo WhiteList { get; set; }
public ConfigInstallServerSignInfo SignIn { get; set; } public ConfigInstallServerSignInfo SignIn { get; set; }
} }
public sealed class ConfigInstallServerSignInfo public sealed class ConfigInstallServerSignInfo
@@ -367,6 +382,14 @@ namespace linker.messenger.store.file
{ {
public string SecretKey { get; set; } public string SecretKey { get; set; }
} }
public sealed class ConfigInstallServerCdkeyInfo
{
public string SecretKey { get; set; }
}
public sealed class ConfigInstallServerWhiteListInfo
{
public string SecretKey { get; set; }
}
public sealed class ConfigInstallServerRelayInfo public sealed class ConfigInstallServerRelayInfo
{ {
public string SecretKey { get; set; } public string SecretKey { get; set; }
@@ -398,6 +421,8 @@ namespace linker.messenger.store.file
public bool Server { get; set; } public bool Server { get; set; }
public bool Group { get; set; } public bool Group { get; set; }
public bool Tunnel { get; set; } public bool Tunnel { get; set; }
public bool Cdkey { get; set; }
public bool WhiteList { get; set; }
} }

View File

@@ -17,7 +17,7 @@ using linker.messenger.signin;
using linker.messenger.socks5; using linker.messenger.socks5;
using linker.messenger.store.file.action; using linker.messenger.store.file.action;
using linker.messenger.store.file.api; using linker.messenger.store.file.api;
using linker.messenger.store.file.cekey; using linker.messenger.store.file.cdkey;
using linker.messenger.store.file.common; using linker.messenger.store.file.common;
using linker.messenger.store.file.firewall; using linker.messenger.store.file.firewall;
using linker.messenger.store.file.forward; using linker.messenger.store.file.forward;
@@ -34,12 +34,14 @@ using linker.messenger.store.file.tunnel;
using linker.messenger.store.file.tuntap; using linker.messenger.store.file.tuntap;
using linker.messenger.store.file.updater; using linker.messenger.store.file.updater;
using linker.messenger.store.file.wakeup; using linker.messenger.store.file.wakeup;
using linker.messenger.store.file.wlist;
using linker.messenger.sync; using linker.messenger.sync;
using linker.messenger.tunnel; using linker.messenger.tunnel;
using linker.messenger.tuntap; using linker.messenger.tuntap;
using linker.messenger.tuntap.lease; using linker.messenger.tuntap.lease;
using linker.messenger.updater; using linker.messenger.updater;
using linker.messenger.wakeup; using linker.messenger.wakeup;
using linker.messenger.wlist;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Text.Json; using System.Text.Json;
namespace linker.messenger.store.file namespace linker.messenger.store.file
@@ -70,7 +72,6 @@ namespace linker.messenger.store.file
serviceCollection.AddSingleton<IRelayServerStore, RelayServerStore>(); serviceCollection.AddSingleton<IRelayServerStore, RelayServerStore>();
serviceCollection.AddSingleton<IRelayServerNodeStore, RelayServerNodeStore>(); serviceCollection.AddSingleton<IRelayServerNodeStore, RelayServerNodeStore>();
serviceCollection.AddSingleton<IRelayServerMasterStore, RelayServerMasterStore>(); serviceCollection.AddSingleton<IRelayServerMasterStore, RelayServerMasterStore>();
serviceCollection.AddSingleton<IRelayServerUser2NodeStore, RelayServerUser2NodeStore>();
serviceCollection.AddSingleton<ICdkeyServerStore, CdkeyServerStore>(); serviceCollection.AddSingleton<ICdkeyServerStore, CdkeyServerStore>();
serviceCollection.AddSingleton<ICdkeyClientStore, CdkeyClientStore>(); serviceCollection.AddSingleton<ICdkeyClientStore, CdkeyClientStore>();
@@ -119,6 +120,8 @@ namespace linker.messenger.store.file
serviceCollection.AddSingleton<IWakeupClientStore, WakeupClientStore>(); serviceCollection.AddSingleton<IWakeupClientStore, WakeupClientStore>();
serviceCollection.AddSingleton<IWhiteListServerStore, WhiteListServerStore>();
serviceCollection.AddSingleton<IWhiteListClientStore, WhiteListClientStore>();
return serviceCollection; return serviceCollection;

View File

@@ -1,6 +1,6 @@
using linker.messenger.cdkey; using linker.messenger.cdkey;
namespace linker.messenger.store.file.cekey namespace linker.messenger.store.file.cdkey
{ {
public sealed class CdkeyClientStore : ICdkeyClientStore public sealed class CdkeyClientStore : ICdkeyClientStore
{ {

View File

@@ -5,7 +5,7 @@ using LiteDB;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace linker.messenger.store.file.relay namespace linker.messenger.store.file.cdkey
{ {
public sealed class CdkeyServerStore : ICdkeyServerStore public sealed class CdkeyServerStore : ICdkeyServerStore
{ {

View File

@@ -1,72 +0,0 @@
using linker.messenger.relay.server;
using LiteDB;
namespace linker.messenger.store.file.relay
{
public sealed class RelayServerUser2NodeStore : IRelayServerUser2NodeStore
{
private readonly ILiteCollection<RelayServerUser2NodeInfo> liteCollection;
public RelayServerUser2NodeStore(Storefactory dBfactory)
{
liteCollection = dBfactory.GetCollection<RelayServerUser2NodeInfo>("relayUser2Node");
}
public async Task<bool> Add(RelayServerUser2NodeInfo info)
{
if (info.Id == 0)
{
info.AddTime = DateTime.Now;
liteCollection.Insert(info);
}
else
{
liteCollection.UpdateMany(p => new RelayServerUser2NodeInfo
{
Name = info.Name,
Remark = info.Remark,
Nodes = info.Nodes,
}, c => c.Id == info.Id);
}
return await Task.FromResult(true).ConfigureAwait(false);
}
public async Task<bool> Del(int id)
{
return await Task.FromResult(liteCollection.Delete(id)).ConfigureAwait(false);
}
public async Task<List<string>> Get(string userid)
{
if (string.IsNullOrWhiteSpace(userid)) return [];
return await Task.FromResult(liteCollection.Find(c => c.UserId == userid).SelectMany(c => c.Nodes).ToList()).ConfigureAwait(false);
}
public async Task<RelayServerUser2NodePageResultInfo> Page(RelayServerUser2NodePageRequestInfo info)
{
ILiteQueryable<RelayServerUser2NodeInfo> query = liteCollection.Query();
if (string.IsNullOrWhiteSpace(info.UserId) == false)
{
query = query.Where(x => x.UserId == info.UserId);
}
if (string.IsNullOrWhiteSpace(info.Name) == false)
{
query = query.Where(x => x.Name.Contains(info.Name));
}
if (string.IsNullOrWhiteSpace(info.Remark) == false)
{
query = query.Where(x => x.Remark.Contains(info.Remark));
}
query = query.OrderBy(c => c.Id, Query.Descending);
return await Task.FromResult(new RelayServerUser2NodePageResultInfo
{
Page = info.Page,
Size = info.Size,
Count = query.Count(),
List = query.Skip((info.Page - 1) * info.Size).Limit(info.Size).ToList()
}).ConfigureAwait(false);
}
}
}

View File

@@ -0,0 +1,20 @@
using linker.messenger.cdkey;
using linker.messenger.wlist;
namespace linker.messenger.store.file
{
public sealed partial class ConfigClientInfo
{
/// <summary>
/// 白名单配置
/// </summary>
public WhiteListConfigInfo WhiteList { get; set; } = new WhiteListConfigInfo();
}
public partial class ConfigServerInfo
{
/// <summary>
/// 白名单配置
/// </summary>
public WhiteListConfigInfo WhiteList { get; set; } = new WhiteListConfigInfo();
}
}

View File

@@ -0,0 +1,22 @@
using linker.messenger.wlist;
namespace linker.messenger.store.file.wlist
{
public sealed class WhiteListClientStore : IWhiteListClientStore
{
public string SecretKey => fileConfig.Data.Client.WhiteList.SecretKey;
private readonly FileConfig fileConfig;
public WhiteListClientStore(FileConfig fileConfig)
{
this.fileConfig = fileConfig;
}
public bool SetSecretKey(string secretKey)
{
fileConfig.Data.Client.WhiteList.SecretKey = secretKey;
fileConfig.Data.Update();
return true;
}
}
}

View File

@@ -0,0 +1,88 @@
using LiteDB;
using linker.messenger.wlist;
namespace linker.messenger.store.file.wlist
{
public sealed class WhiteListServerStore : IWhiteListServerStore
{
private readonly ILiteCollection<WhiteListInfo> liteCollection;
private readonly FileConfig fileConfig;
public WhiteListServerStore(Storefactory dBfactory, FileConfig fileConfig)
{
liteCollection = dBfactory.GetCollection<WhiteListInfo>("whiteList");
this.fileConfig = fileConfig;
}
public bool ValidateSecretKey(string secretKey)
{
return secretKey == fileConfig.Data.Server.WhiteList.SecretKey;
}
public async Task<bool> Add(WhiteListInfo info)
{
if (info.Id == 0)
{
info.AddTime = DateTime.Now;
liteCollection.Insert(info);
}
else
{
liteCollection.UpdateMany(p => new WhiteListInfo
{
Name = info.Name,
Remark = info.Remark,
Nodes = info.Nodes,
}, c => c.Id == info.Id);
}
return await Task.FromResult(true).ConfigureAwait(false);
}
public async Task<bool> Del(int id)
{
return await Task.FromResult(liteCollection.Delete(id)).ConfigureAwait(false);
}
public async Task<List<string>> Get(string type, string userid)
{
if (string.IsNullOrWhiteSpace(type) || string.IsNullOrWhiteSpace(userid)) return [];
return await Task.FromResult(liteCollection.Find(c => c.Type == type && c.UserId == userid).SelectMany(c => c.Nodes).ToList()).ConfigureAwait(false);
}
public async Task<WhiteListPageResultInfo> Page(WhiteListPageRequestInfo info)
{
if (string.IsNullOrWhiteSpace(info.Type))
{
return new WhiteListPageResultInfo
{
Page = info.Page,
Size = info.Size,
Count = 0,
List = []
};
}
ILiteQueryable<WhiteListInfo> query = liteCollection.Query().Where(c => c.Type == info.Type);
if (string.IsNullOrWhiteSpace(info.UserId) == false)
{
query = query.Where(x => x.UserId == info.UserId);
}
if (string.IsNullOrWhiteSpace(info.Name) == false)
{
query = query.Where(x => x.Name.Contains(info.Name));
}
if (string.IsNullOrWhiteSpace(info.Remark) == false)
{
query = query.Where(x => x.Remark.Contains(info.Remark));
}
query = query.OrderBy(c => c.Id, Query.Descending);
return await Task.FromResult(new WhiteListPageResultInfo
{
Page = info.Page,
Size = info.Size,
Count = query.Count(),
List = query.Skip((info.Page - 1) * info.Size).Limit(info.Size).ToList()
}).ConfigureAwait(false);
}
}
}

View File

@@ -94,7 +94,7 @@ namespace linker.messenger.tunnel
data[i] = (byte)(data[i] ^ byte.MaxValue); data[i] = (byte)(data[i] ^ byte.MaxValue);
} }
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32))); byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Sha256().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(data.AsMemory(1 + length + 2)); temp.AsMemory().CopyTo(data.AsMemory(1 + length + 2));
return data.AsMemory(0, 1 + length + 2 + temp.Length); return data.AsMemory(0, 1 + length + 2 + temp.Length);

View File

@@ -0,0 +1,41 @@
using linker.libs.web;
using linker.messenger.sync;
using Microsoft.Extensions.DependencyInjection;
namespace linker.messenger.wlist
{
public static class Entry
{
public static ServiceCollection AddWhiteListClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<WhiteListApiController>();
serviceCollection.AddSingleton<WhitelistConfigSyncSecretKey>();
return serviceCollection;
}
public static ServiceProvider UseWhiteListClient(this ServiceProvider serviceProvider)
{
SyncTreansfer syncTransfer = serviceProvider.GetService<SyncTreansfer>();
syncTransfer.AddSyncs(new List<ISync> { serviceProvider.GetService<WhitelistConfigSyncSecretKey>() });
linker.messenger.api.IWebServer apiServer = serviceProvider.GetService<linker.messenger.api.IWebServer>();
apiServer.AddPlugins(new List<IApiController> { serviceProvider.GetService<WhiteListApiController>() });
return serviceProvider;
}
public static ServiceCollection AddWhiteListServer(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<WhiteListServerMessenger>();
return serviceCollection;
}
public static ServiceProvider UseWhiteListServer(this ServiceProvider serviceProvider)
{
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<WhiteListServerMessenger>() });
return serviceProvider;
}
}
}

View File

@@ -0,0 +1,15 @@
namespace linker.messenger.wlist
{
public interface IWhiteListClientStore
{
public string SecretKey { get; }
/// <summary>
/// 设置密钥
/// </summary>
/// <param name="secretKey"></param>
/// <returns></returns>
public bool SetSecretKey(string secretKey);
}
}

View File

@@ -0,0 +1,64 @@
using linker.libs;
namespace linker.messenger.wlist
{
public interface IWhiteListServerStore
{
public bool ValidateSecretKey(string secretKey);
public Task<WhiteListPageResultInfo> Page(WhiteListPageRequestInfo request);
public Task<bool> Add(WhiteListInfo info);
public Task<bool> Del(int id);
public Task<List<string>> Get(string type, string userid);
}
public sealed partial class WhiteListDelInfo
{
public string SecretKey { get; set; }
public int Id { get; set; }
}
public sealed partial class WhiteListAddInfo
{
public string SecretKey { get; set; }
public WhiteListInfo Data { get; set; }
}
public sealed partial class WhiteListPageRequestInfo
{
public int Page { get; set; }
public int Size { get; set; }
public string Type { get; set; }
public string UserId { get; set; }
public string Name { get; set; }
public string Remark { get; set; }
public string SecretKey { get; set; }
}
public sealed partial class WhiteListPageResultInfo
{
public int Page { get; set; }
public int Size { get; set; }
public int Count { get; set; }
public List<WhiteListInfo> List { get; set; }
}
public sealed partial class WhiteListInfo
{
public int Id { get; set; }
public string Type { get; set; } = string.Empty;
public string UserId { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Remark { get; set; } = string.Empty;
public DateTime AddTime { get; set; } = DateTime.Now;
public string[] Nodes { get; set; } = [];
}
public sealed class WhiteListConfigInfo
{
/// <summary>
/// 加解密密钥
/// </summary>
#if DEBUG
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
}
}

View File

@@ -0,0 +1,115 @@
using linker.libs;
using linker.libs.extends;
using linker.libs.web;
using linker.messenger.signin;
namespace linker.messenger.wlist
{
/// <summary>
/// 中继管理接口
/// </summary>
public sealed class WhiteListApiController : IApiController
{
private readonly SignInClientState signInClientState;
private readonly IMessengerSender messengerSender;
private readonly ISerializer serializer;
private readonly IWhiteListClientStore whiteListClientStore;
public WhiteListApiController(SignInClientState signInClientState, IMessengerSender messengerSender, ISerializer serializer, IWhiteListClientStore whiteListClientStore)
{
this.signInClientState = signInClientState;
this.messengerSender = messengerSender;
this.serializer = serializer;
this.whiteListClientStore = whiteListClientStore;
}
public string GetSecretKey(ApiControllerParamsInfo param)
{
return whiteListClientStore.SecretKey;
}
public void SetSecretKey(ApiControllerParamsInfo param)
{
whiteListClientStore.SetSecretKey(param.Content);
}
/// 检查密钥
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<bool> CheckKey(ApiControllerParamsInfo param)
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)WhiteListMessengerIds.CheckKey,
Payload = serializer.Serialize(whiteListClientStore.SecretKey)
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
/// <summary>
/// 添加修改
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<bool> Add(ApiControllerParamsInfo param)
{
WhiteListInfo info = param.Content.DeJson<WhiteListInfo>();
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)WhiteListMessengerIds.Add,
Payload = serializer.Serialize(new WhiteListAddInfo
{
Data = info,
SecretKey = whiteListClientStore.SecretKey
})
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<bool> Del(ApiControllerParamsInfo param)
{
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)WhiteListMessengerIds.Del,
Payload = serializer.Serialize(new WhiteListDelInfo
{
Id = int.Parse(param.Content),
SecretKey = whiteListClientStore.SecretKey
})
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
/// <summary>
/// 用分页查询
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<WhiteListPageResultInfo> Page(ApiControllerParamsInfo param)
{
WhiteListPageRequestInfo info = param.Content.DeJson<WhiteListPageRequestInfo>();
info.SecretKey = whiteListClientStore.SecretKey;
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)WhiteListMessengerIds.Page,
Payload = serializer.Serialize(info)
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK)
{
return serializer.Deserialize<WhiteListPageResultInfo>(resp.Data.Span);
}
return new WhiteListPageResultInfo();
}
}
}

View File

@@ -0,0 +1,27 @@
using linker.libs;
using linker.messenger.sync;
namespace linker.messenger.wlist
{
public sealed class WhitelistConfigSyncSecretKey : ISync
{
public string Name => "WhiteListSecretKey";
private readonly ISerializer serializer;
private readonly IWhiteListClientStore whiteListClientStore;
public WhitelistConfigSyncSecretKey(ISerializer serializer, IWhiteListClientStore whiteListClientStore)
{
this.serializer = serializer;
this.whiteListClientStore = whiteListClientStore;
}
public Memory<byte> GetData()
{
return serializer.Serialize(whiteListClientStore.SecretKey);
}
public void SetData(Memory<byte> data)
{
whiteListClientStore.SetSecretKey(serializer.Deserialize<string>(data.Span));
}
}
}

View File

@@ -0,0 +1,104 @@
using linker.libs;
using linker.messenger.signin;
namespace linker.messenger.wlist
{
/// <summary>
/// 中继服务端
/// </summary>
public class WhiteListServerMessenger : IMessenger
{
private readonly IMessengerSender messengerSender;
private readonly SignInServerCaching signCaching;
private readonly ISerializer serializer;
private readonly IWhiteListServerStore whiteListServerStore;
public WhiteListServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, IWhiteListServerStore whiteListServerStore)
{
this.messengerSender = messengerSender;
this.signCaching = signCaching;
this.serializer = serializer;
this.whiteListServerStore = whiteListServerStore;
}
/// <summary>
/// 添加
/// </summary>
/// <param name="connection"></param>
[MessengerId((ushort)WhiteListMessengerIds.Add)]
public async Task Add(IConnection connection)
{
WhiteListAddInfo info = serializer.Deserialize<WhiteListAddInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(Helper.FalseArray);
return;
}
if (whiteListServerStore.ValidateSecretKey(info.SecretKey) == false)
{
connection.Write(Helper.FalseArray);
return;
}
await whiteListServerStore.Add(info.Data).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)WhiteListMessengerIds.Del)]
public async Task Del(IConnection connection)
{
WhiteListDelInfo info = serializer.Deserialize<WhiteListDelInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(Helper.FalseArray);
return;
}
if (whiteListServerStore.ValidateSecretKey(info.SecretKey) == false)
{
connection.Write(Helper.FalseArray);
return;
}
await whiteListServerStore.Del(info.Id).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
}
/// <summary>
/// 查询
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
[MessengerId((ushort)WhiteListMessengerIds.Page)]
public async Task Page(IConnection connection)
{
WhiteListPageRequestInfo info = serializer.Deserialize<WhiteListPageRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
{
connection.Write(serializer.Serialize(new WhiteListPageResultInfo { }));
return;
}
if (whiteListServerStore.ValidateSecretKey(info.SecretKey) == false && string.IsNullOrWhiteSpace(info.UserId))
{
connection.Write(serializer.Serialize(new WhiteListPageResultInfo { }));
return;
}
var page = await whiteListServerStore.Page(info).ConfigureAwait(false);
connection.Write(serializer.Serialize(page));
}
[MessengerId((ushort)WhiteListMessengerIds.CheckKey)]
public void CheckKey(IConnection connection)
{
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(whiteListServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
}
}
}

View File

@@ -0,0 +1,14 @@
namespace linker.messenger.wlist
{
public enum WhiteListMessengerIds : ushort
{
Min = 3700,
Add = 3701,
Page = 3702,
Del = 3703,
CheckKey = 3704,
Max = 3599
}
}

View File

@@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>false</PublishAot>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
<EnablePreviewFeatures>True</EnablePreviewFeatures>
<Title>linker messenger white list</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>linker messenger white list</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger white list</PackageReleaseNotes>
<Version>1.8.5</Version>
<AssemblyVersion>1.8.5</AssemblyVersion>
<FileVersion>1.8.5</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
<ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.messenger.sync\linker.messenger.sync.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
</ItemGroup>
</Project>

View File

@@ -102,7 +102,7 @@ namespace linker.tunnel.connection
{ {
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"tunnel connection writer offline 0"); LoggerHelper.Instance.Error($"tunnel connection writer offline 0");
break; continue;
} }
await CallbackPacket(buffer, 0, result.ReceivedBytes).ConfigureAwait(false); await CallbackPacket(buffer, 0, result.ReceivedBytes).ConfigureAwait(false);
} }

View File

@@ -482,7 +482,7 @@ namespace linker.tunnel.transport
while (true) while (true)
{ {
SocketReceiveFromResult result = await token.RemoteUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false); SocketReceiveFromResult result = await token.RemoteUdp.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false);
if (result.ReceivedBytes == 0) return; if (result.ReceivedBytes == 0) continue;
Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes); Memory<byte> memory = buffer.AsMemory(0, result.ReceivedBytes);
@@ -573,7 +573,7 @@ namespace linker.tunnel.transport
SocketReceiveFromResult result = await local.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false); SocketReceiveFromResult result = await local.ReceiveFromAsync(buffer, tempEp).ConfigureAwait(false);
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
break; continue;
} }
if (result.ReceivedBytes == endBytes.Length && buffer.AsMemory(0, result.ReceivedBytes).Span.SequenceEqual(endBytes)) if (result.ReceivedBytes == endBytes.Length && buffer.AsMemory(0, result.ReceivedBytes).Span.SequenceEqual(endBytes))
{ {

View File

@@ -95,7 +95,7 @@ namespace linker.tunnel.transport
SocketReceiveFromResult result = await socket.ReceiveFromAsync(bytes.AsMemory(), ep).ConfigureAwait(false); SocketReceiveFromResult result = await socket.ReceiveFromAsync(bytes.AsMemory(), ep).ConfigureAwait(false);
if (result.ReceivedBytes == 0) if (result.ReceivedBytes == 0)
{ {
break; continue;
} }
IPEndPoint remoteEP = result.RemoteEndPoint as IPEndPoint; IPEndPoint remoteEP = result.RemoteEndPoint as IPEndPoint;

View File

@@ -75,7 +75,7 @@ namespace linker.tunnel.wanport
} }
private static Memory<byte> BuildSendData(byte[] buffer, byte i) private static Memory<byte> BuildSendData(byte[] buffer, byte i)
{ {
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32))); byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Sha256().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(buffer); temp.AsMemory().CopyTo(buffer);
buffer[0] = 0; buffer[0] = 0;
buffer[1] = i; buffer[1] = i;
@@ -141,7 +141,7 @@ namespace linker.tunnel.wanport
private static Memory<byte> BuildSendData(byte[] buffer, byte i) private static Memory<byte> BuildSendData(byte[] buffer, byte i)
{ {
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32))); byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Sha256().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(buffer); temp.AsMemory().CopyTo(buffer);
buffer[0] = 0; buffer[0] = 0;
buffer[1] = i; buffer[1] = i;

View File

@@ -21,16 +21,6 @@ export const relayConnect = (data) => {
export const relayUpdateNode = (data) => { export const relayUpdateNode = (data) => {
return sendWebsocketMsg('relay/UpdateNode', data); return sendWebsocketMsg('relay/UpdateNode', data);
} }
export const checkRelayKey = (key) => { export const checkRelayKey = () => {
return sendWebsocketMsg('relay/checkkey',key); return sendWebsocketMsg('relay/checkkey');
}
export const user2NodePage = (data) => {
return sendWebsocketMsg('relay/PageUser2Node', data);
}
export const user2NodeAdd = (data) => {
return sendWebsocketMsg('relay/AddUser2Node', data);
}
export const user2NodeDel = (data) => {
return sendWebsocketMsg('relay/DelUser2Node', data);
} }

View File

@@ -32,6 +32,6 @@ export const startSForwardInfo = (data) => {
export const stopSForwardInfo = (data) => { export const stopSForwardInfo = (data) => {
return sendWebsocketMsg('sforward/stop', data); return sendWebsocketMsg('sforward/stop', data);
} }
export const checkSForwardKey = (key) => { export const checkSForwardKey = () => {
return sendWebsocketMsg('sforward/checkkey',key); return sendWebsocketMsg('sforward/checkkey');
} }

View File

@@ -45,6 +45,6 @@ export const subscribeUpdater = () => {
export const checkUpdater = (data) => { export const checkUpdater = (data) => {
return sendWebsocketMsg('updater/check', data); return sendWebsocketMsg('updater/check', data);
} }
export const checkUpdaterKey = (key) => { export const checkUpdaterKey = () => {
return sendWebsocketMsg('updater/checkkey',key); return sendWebsocketMsg('updater/checkkey');
} }

View File

@@ -0,0 +1,20 @@
import { sendWebsocketMsg } from './request'
export const getSecretKey = () => {
return sendWebsocketMsg('whitelist/GetSecretKey');
}
export const setSecretKey = (data) => {
return sendWebsocketMsg('whitelist/SetSecretKey', data);
}
export const checkKey = () => {
return sendWebsocketMsg('whitelist/CheckKey');
}
export const wlistPage = (data) => {
return sendWebsocketMsg('whitelist/Page', data);
}
export const wlistAdd = (data) => {
return sendWebsocketMsg('whitelist/Add', data);
}
export const wlistDel = (data) => {
return sendWebsocketMsg('whitelist/Del', data);
}

View File

@@ -81,6 +81,8 @@ export default {
'status.exportServer': 'Messenger server', 'status.exportServer': 'Messenger server',
'status.exportGroup': 'Group', 'status.exportGroup': 'Group',
'status.exportTunnel': 'Tunnel config', 'status.exportTunnel': 'Tunnel config',
'status.exportCdkey': 'Cdkey secretKey',
'status.exportWhiteList': 'White list secretKey',
'status.api': 'Manager api', 'status.api': 'Manager api',
'status.apiClear': 'Clear', 'status.apiClear': 'Clear',
@@ -232,6 +234,21 @@ export default {
'server.cdkeyImportNetwork': 'Network error', 'server.cdkeyImportNetwork': 'Network error',
'server.cdkeyImportOrderId': 'OrderNo has exists', 'server.cdkeyImportOrderId': 'OrderNo has exists',
'server.wlist': 'White list',
'server.wlistSecretKey': 'White list secretKey',
'server.wlistText': 'White list manager',
'server.wlistUserId': 'User id',
'server.wlistName': 'Name',
'server.wlistRemark': 'Remark',
'server.wlistAddTime': 'Add time',
'server.wlistNodes': 'Value',
'server.wlistNodesRelay': 'Nodes',
'server.wlistOper': 'Oper',
'server.wlistDelConfirm': 'Are you sure to delete',
'server.wlistAdd': 'Add',
'server.wlistUnselect': 'Unselect',
'server.wlistSelected': 'Selected',
'server.sforwardSecretKey': 'Server forward secretKey', 'server.sforwardSecretKey': 'Server forward secretKey',
'server.sforwardText': 'The server forward can be used when the key is correct', 'server.sforwardText': 'The server forward can be used when the key is correct',

View File

@@ -81,6 +81,8 @@ export default {
'status.exportServer': '信标服务器', 'status.exportServer': '信标服务器',
'status.exportGroup': '当前分组', 'status.exportGroup': '当前分组',
'status.exportTunnel': '打洞协议', 'status.exportTunnel': '打洞协议',
'status.exportCdkey': 'cdkey密钥',
'status.exportWhiteList': '白名单密钥',
'status.api': '管理接口', 'status.api': '管理接口',
'status.apiClear': '清除', 'status.apiClear': '清除',
@@ -254,17 +256,6 @@ export default {
'server.relayDefault': '默认', 'server.relayDefault': '默认',
'server.relaySetDefault': '设置默认中继节点', 'server.relaySetDefault': '设置默认中继节点',
'server.relaySetDefaultText': '不选择则所有客户端', 'server.relaySetDefaultText': '不选择则所有客户端',
'server.relayUser2Node': '中继白名单',
'server.relayUser2NodeUserId': '用户编号',
'server.relayUser2NodeName': '名称',
'server.relayUser2NodeRemark': '备注',
'server.relayUser2NodeAddTime': '添加时间',
'server.relayUser2NodeNodes': '节点',
'server.relayUser2NodeOper': '操作',
'server.relayUser2NodeDelConfirm': '确认删除吗?',
'server.relayUser2NodeAdd': '添加白名单',
'server.relayUser2NodeUnselect': '未选择',
'server.relayUser2NodeSelected': '已选择',
'server.cdkeySecretKey': 'Cdkey密钥', 'server.cdkeySecretKey': 'Cdkey密钥',
'server.cdkeyText': '密钥正确时可管理cdkey', 'server.cdkeyText': '密钥正确时可管理cdkey',
@@ -334,12 +325,27 @@ export default {
'server.cdkeyImportNetwork': '网络错误', 'server.cdkeyImportNetwork': '网络错误',
'server.cdkeyImportOrderId': '订单号已存在', 'server.cdkeyImportOrderId': '订单号已存在',
'server.wlist': '白名单',
'server.wlistSecretKey': '白名单密钥',
'server.wlistText': '密钥正确时可管理白名单',
'server.wlistUserId': '用户编号',
'server.wlistName': '名称',
'server.wlistRemark': '备注',
'server.wlistAddTime': '添加时间',
'server.wlistNodes': '内容',
'server.wlistNodesRelay': '节点',
'server.wlistOper': '操作',
'server.wlistDelConfirm': '确认删除吗?',
'server.wlistAdd': '添加白名单',
'server.wlistUnselect': '未选择',
'server.wlistSelected': '已选择',
'server.sforwardSecretKey': '服务器穿透密钥', 'server.sforwardSecretKey': '服务器穿透密钥',
'server.sforwardText': '密钥正确是可用', 'server.sforwardText': '密钥正确时可使用服务器穿透',
'server.updaterSecretKey': '服务器更新密钥', 'server.updaterSecretKey': '服务器更新密钥',
'server.updaterSync2Server': '自动更新到服务器版本', 'server.updaterSync2Server': '自动更新到服务器版本',
'server.updaterText': '密钥正确是可用', 'server.updaterText': '密钥正确时可更新本服务器客户端',
'server.updaterRate': '检查更新频率', 'server.updaterRate': '检查更新频率',
'server.updaterY': '年', 'server.updaterY': '年',
'server.updaterM': '月', 'server.updaterM': '月',
@@ -414,4 +420,6 @@ export default {
'wakeup.runSwitchLong': '长按', 'wakeup.runSwitchLong': '长按',
'wakeup.runSwitchTouch': '轻触', 'wakeup.runSwitchTouch': '轻触',
'wakeup.runSwitchCustom': '自定义ms', 'wakeup.runSwitchCustom': '自定义ms',
} }

View File

@@ -77,6 +77,20 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="" label-width="0" v-if="state.form.hasServer">
<el-row class="w-100">
<el-col :sm="12" :xs="24">
<el-form-item label="cdkey密钥" prop="cdkeySecretKey">
<el-input v-model="state.form.cdkeySecretKey" maxlength="36" show-word-limit />
</el-form-item>
</el-col>
<el-col :sm="12" :xs="24">
<el-form-item label="白名单密钥" prop="whiteListSecretKey">
<el-input v-model="state.form.whiteListSecretKey" maxlength="36" show-word-limit />
</el-form-item>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="" label-width="0" v-if="state.form.hasServer"> <el-form-item label="" label-width="0" v-if="state.form.hasServer">
<el-row class="w-100"> <el-row class="w-100">
<el-col :sm="12" :xs="24"> <el-col :sm="12" :xs="24">
@@ -117,6 +131,8 @@ export default {
sForwardSecretKey:step.value.form.client.sForwardSecretKey ||globalData.value.config.Client.SForward.SecretKey, sForwardSecretKey:step.value.form.client.sForwardSecretKey ||globalData.value.config.Client.SForward.SecretKey,
relaySecretKey:step.value.form.client.relaySecretKey ||(globalData.value.config.Client.Relay.Servers[0] || {SecretKey:'snltty'}).SecretKey, relaySecretKey:step.value.form.client.relaySecretKey ||(globalData.value.config.Client.Relay.Servers[0] || {SecretKey:'snltty'}).SecretKey,
updaterSecretKey:step.value.form.client.updaterSecretKey ||globalData.value.config.Client.Updater.SecretKey, updaterSecretKey:step.value.form.client.updaterSecretKey ||globalData.value.config.Client.Updater.SecretKey,
cdkeySecretKey:step.value.form.client.cdkeySecretKey ||globalData.value.config.Client.Cdkey.SecretKey,
whiteListSecretKey:step.value.form.client.whiteListSecretKey ||globalData.value.config.Client.WhiteList.SecretKey,
}, },
rules: { rules: {
name: [{ required: true, message: "必填", trigger: "blur" }], name: [{ required: true, message: "必填", trigger: "blur" }],
@@ -158,6 +174,8 @@ export default {
sForwardSecretKey: state.form.sForwardSecretKey, sForwardSecretKey: state.form.sForwardSecretKey,
relaySecretKey: state.form.relaySecretKey, relaySecretKey: state.form.relaySecretKey,
updaterSecretKey: state.form.updaterSecretKey, updaterSecretKey: state.form.updaterSecretKey,
cdkeySecretKey: state.form.cdkeySecretKey,
whiteListSecretKey: state.form.whiteListSecretKey,
} }
}, },
form:{ form:{

View File

@@ -32,8 +32,8 @@
<el-form-item label="" label-width="0"> <el-form-item label="" label-width="0">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="穿透密钥" prop="sForwardSecretKey"> <el-form-item label="信标密钥" prop="signinSecretKey">
<el-input v-model="state.form.sForwardSecretKey" maxlength="36" show-word-limit /> <el-input v-model="state.form.signinSecretKey" maxlength="36" show-word-limit />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@@ -46,8 +46,8 @@
<el-form-item label="" label-width="0"> <el-form-item label="" label-width="0">
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="信标密钥" prop="signinSecretKey"> <el-form-item label="穿透密钥" prop="sForwardSecretKey">
<el-input v-model="state.form.signinSecretKey" maxlength="36" show-word-limit /> <el-input v-model="state.form.sForwardSecretKey" maxlength="36" show-word-limit />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@@ -57,6 +57,20 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
<el-form-item label="" label-width="0">
<el-row>
<el-col :span="12">
<el-form-item label="cdkey密钥" prop="cdkeySecretKey">
<el-input v-model="state.form.cdkeySecretKey" maxlength="36" show-word-limit />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="白名单密钥" prop="whiteListSecretKey">
<el-input v-model="state.form.whiteListSecretKey" maxlength="36" show-word-limit />
</el-form-item>
</el-col>
</el-row>
</el-form-item>
</el-form> </el-form>
</div> </div>
@@ -81,10 +95,15 @@ export default {
tunnelPort2:step.value.form.server.tunnelPort2 ||globalData.value.config.Server.SForward.TunnelPortRange[1], tunnelPort2:step.value.form.server.tunnelPort2 ||globalData.value.config.Server.SForward.TunnelPortRange[1],
updaterSecretKey:step.value.form.server.updaterSecretKey ||globalData.value.config.Server.Updater.SecretKey, updaterSecretKey:step.value.form.server.updaterSecretKey ||globalData.value.config.Server.Updater.SecretKey,
cdkeySecretKey:step.value.form.server.cdkeySecretKey ||globalData.value.config.Server.Cdkey.SecretKey,
whiteListSecretKey:step.value.form.server.whiteListSecretKey ||globalData.value.config.Server.WhiteList.SecretKey,
}, },
rules: { rules: {
relaySecretKey: [{ required: true, message: "必填", trigger: "blur" }], relaySecretKey: [{ required: true, message: "必填", trigger: "blur" }],
sForwardSecretKey: [{ required: true, message: "必填", trigger: "blur" }], sForwardSecretKey: [{ required: true, message: "必填", trigger: "blur" }],
updaterSecretKey: [{ required: true, message: "必填", trigger: "blur" }],
cdkeySecretKey: [{ required: true, message: "必填", trigger: "blur" }],
whiteListSecretKey: [{ required: true, message: "必填", trigger: "blur" }],
servicePort: [ servicePort: [
{ required: true, message: "必填", trigger: "blur" }, { required: true, message: "必填", trigger: "blur" },
{ {
@@ -164,6 +183,12 @@ export default {
}, },
SignIn:{ SignIn:{
SecretKey: state.form.signinSecretKey SecretKey: state.form.signinSecretKey
},
Cdkey:{
SecretKey: state.form.cdkeySecretKey
},
WhiteList:{
SecretKey: state.form.whiteListSecretKey
} }
} }
}, },

View File

@@ -13,7 +13,7 @@
<a href="javascript:;" @click="state.showModes=true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}"> <a href="javascript:;" @click="state.showModes=true" class="mgr-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
{{$t('server.relayNodes')}} : {{state.nodes.length}} {{$t('server.relayNodes')}} : {{state.nodes.length}}
</a> </a>
<User2Node :keyState="state.keyState"></User2Node> <WhiteList type="Relay"></WhiteList>
<div class="mgr-1" :title="$t('server.relayUseCdkeyTitle')"> <div class="mgr-1" :title="$t('server.relayUseCdkeyTitle')">
<el-checkbox v-model="state.list.UseCdkey" :label="$t('server.relayUseCdkey')" @change="handleSave" /> <el-checkbox v-model="state.list.UseCdkey" :label="$t('server.relayUseCdkey')" @change="handleSave" />
</div> </div>
@@ -32,10 +32,10 @@ import { useI18n } from 'vue-i18n';
import Sync from '../sync/Index.vue' import Sync from '../sync/Index.vue'
import Cdkey from './cdkey/Index.vue' import Cdkey from './cdkey/Index.vue'
import Nodes from './relay/Nodes.vue'; import Nodes from './relay/Nodes.vue';
import User2Node from './user2node/Index.vue'; import WhiteList from './wlist/Index.vue';
export default { export default {
components:{Sync,Cdkey,Nodes,User2Node}, components:{Sync,Cdkey,Nodes,WhiteList},
setup(props) { setup(props) {
const {t} = useI18n(); const {t} = useI18n();
const globalData = injectGlobalData(); const globalData = injectGlobalData();
@@ -69,7 +69,7 @@ export default {
}); });
} }
const handleCheckKey = ()=>{ const handleCheckKey = ()=>{
checkRelayKey(state.list.SecretKey).then((res)=>{ checkRelayKey().then((res)=>{
state.keyState = res; state.keyState = res;
}).catch(()=>{}); }).catch(()=>{});
} }

View File

@@ -6,9 +6,9 @@
<Sync class="mgl-1" name="SForwardSecretKey"></Sync> <Sync class="mgl-1" name="SForwardSecretKey"></Sync>
<span class="mgl-1" v-if="globalData.isPc">{{$t('server.sforwardText')}}</span> <span class="mgl-1" v-if="globalData.isPc">{{$t('server.sforwardText')}}</span>
</div> </div>
<div class="flex"> <!-- <div class="flex">
<Cdkey type="SForward"></Cdkey> <Cdkey type="SForward"></Cdkey>
</div> </div> -->
</div> </div>
</el-form-item> </el-form-item>
</template> </template>
@@ -51,7 +51,7 @@ export default {
handleCheckKey(); handleCheckKey();
} }
const handleCheckKey = ()=>{ const handleCheckKey = ()=>{
checkSForwardKey(state.SForwardSecretKey).then((res)=>{ checkSForwardKey().then((res)=>{
state.keyState = res; state.keyState = res;
}); });
} }

View File

@@ -31,6 +31,7 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item></el-form-item> <el-form-item></el-form-item>
<WhiteList></WhiteList>
<Cdkey></Cdkey> <Cdkey></Cdkey>
<RelayServers class="mgt-2"></RelayServers> <RelayServers class="mgt-2"></RelayServers>
<SForward></SForward> <SForward></SForward>
@@ -54,11 +55,12 @@ import { computed, onMounted, reactive } from 'vue'
import SForward from './SForward.vue'; import SForward from './SForward.vue';
import Updater from './Updater.vue'; import Updater from './Updater.vue';
import Cdkey from './Cdkey.vue'; import Cdkey from './Cdkey.vue';
import WhiteList from './WhiteList.vue';
import RelayServers from './RelayServers.vue'; import RelayServers from './RelayServers.vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import Sync from '../sync/Index.vue' import Sync from '../sync/Index.vue'
export default { export default {
components:{SForward,Updater,Cdkey,RelayServers,Sync}, components:{SForward,Updater,WhiteList,Cdkey,RelayServers,Sync},
setup(props) { setup(props) {
const {t} = useI18n(); const {t} = useI18n();
const globalData = injectGlobalData(); const globalData = injectGlobalData();

View File

@@ -60,7 +60,7 @@ export default {
} }
const handleCheckKey = ()=>{ const handleCheckKey = ()=>{
checkUpdaterKey(state.secretKey).then((res)=>{ checkUpdaterKey().then((res)=>{
state.keyState = res; state.keyState = res;
}).catch(()=>{}); }).catch(()=>{});
} }

View File

@@ -0,0 +1,63 @@
<template>
<el-form-item :label="$t('server.wlistSecretKey')">
<div class="flex">
<el-input :class="{success:state.keyState,error:state.keyState==false}" style="width:20rem;" type="password" show-password v-model="state.secretKey" maxlength="36" @blur="handleChange"/>
<Sync class="mgl-1" name="WhiteListSecretKey"></Sync>
<span class="mgl-1" v-if="globalData.isPc">{{$t('server.wlistText')}}</span>
</div>
</el-form-item>
</template>
<script>
import { checkKey, getSecretKey,setSecretKey } from '@/apis/wlist';
import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus';
import { onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n';
import Sync from '../sync/Index.vue'
export default {
components:{Sync},
setup(props) {
const {t} = useI18n();
const globalData = injectGlobalData();
const state = reactive({
secretKey:'',
keyState:false,
});
const _getSecretKey = ()=>{
getSecretKey().then((res)=>{
state.secretKey = res;
handleCheckKey();
});
}
const _setSecretKey = ()=>{
if(!state.secretKey) return;
setSecretKey(state.secretKey).then(()=>{
ElMessage.success(t('common.oper'));
}).catch((err)=>{
console.log(err);
ElMessage.error(t('common.operFail'));
});
}
const handleChange = ()=>{
_setSecretKey();
handleCheckKey();
}
const handleCheckKey = ()=>{
checkKey().then((res)=>{
state.keyState = res;
}).catch(()=>{});
}
onMounted(()=>{
_getSecretKey();
});
return {globalData,state,handleChange}
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -1,29 +0,0 @@
<template>
<a v-if="state.hasUser2Node && hasUser2Node" @click="state.showManager = true" href="javascript:;" class="mgr-1 a-line">{{$t('server.relayUser2Node')}}</a>
<Manager v-if="state.showManager" v-model="state.showManager" />
</template>
<script>
import { injectGlobalData } from '@/provide';
import { computed, reactive } from 'vue';
import Manager from './Manager.vue'
export default {
props:['keyState'],
components:{Manager},
setup (props) {
const globalData = injectGlobalData();
const hasUser2Node = computed(()=>globalData.value.hasAccess('User2Node'));
const state = reactive({
hasUser2Node:computed(()=>props.keyState),
showManager:false
});
return {state,hasUser2Node}
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -1,17 +1,17 @@
<template> <template>
<el-dialog class="options-center" :title="$t('server.relayUser2Node')" destroy-on-close v-model="state.show" width="36rem" top="2vh"> <el-dialog class="options-center" :title="$t('server.wlist')" destroy-on-close v-model="state.show" width="36rem" top="2vh">
<div> <div>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto"> <el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('server.relayUser2NodeUserId')" prop="UserId"> <el-form-item :label="$t('server.wlistUserId')" prop="UserId">
<el-input maxlength="36" show-word-limit v-model="state.ruleForm.UserId" /> <el-input maxlength="36" show-word-limit v-model="state.ruleForm.UserId" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('server.relayUser2NodeName')" prop="Name"> <el-form-item :label="$t('server.wlistName')" prop="Name">
<el-input v-model="state.ruleForm.Name" /> <el-input v-model="state.ruleForm.Name" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('server.relayUser2NodeNodes')" prop="Nodes"> <el-form-item :label="$t(`server.wlistNodes${state.ruleForm.Type}`)" prop="Nodes">
<el-input type="textarea" :value="state.nodes" @click="handleShowNodes" readonly resize="none" rows="4"></el-input> <el-input type="textarea" :value="state.nodes" @click="handleShowNodes" readonly resize="none" rows="4"></el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('server.relayUser2NodeRemark')" prop="Remark"> <el-form-item :label="$t('server.wlistRemark')" prop="Remark">
<el-input v-model="state.ruleForm.Remark" /> <el-input v-model="state.ruleForm.Remark" />
</el-form-item> </el-form-item>
<el-form-item></el-form-item> <el-form-item></el-form-item>
@@ -24,14 +24,14 @@
</el-form> </el-form>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog class="options-center" :title="$t('server.relayUser2NodeNodes')" destroy-on-close v-model="state.showNodes" width="54rem" top="2vh"> <el-dialog class="options-center" :title="$t('server.wlistNodes')" destroy-on-close v-model="state.showNodes" width="54rem" top="2vh">
<div> <div>
<el-transfer class="src-tranfer" <el-transfer class="src-tranfer"
v-model="state.nodeIds" v-model="state.nodeIds"
filterable filterable
:filter-method="srcFilterMethod" :filter-method="srcFilterMethod"
:data="nodes" :data="nodes"
:titles="[$t('server.relayUser2NodeUnselect'), $t('server.relayUser2NodeSelected')]" :titles="[$t('server.wlistUnselect'), $t('server.wlistSelected')]"
:props="{ :props="{
key: 'Id', key: 'Id',
label: 'Name', label: 'Name',
@@ -49,7 +49,7 @@
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed, inject, reactive, ref, watch } from 'vue' import { computed, inject, reactive, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { user2NodeAdd } from '@/apis/relay'; import { wlistAdd } from '@/apis/wlist';
export default { export default {
props: ['modelValue'], props: ['modelValue'],
emits: ['update:modelValue','success'], emits: ['update:modelValue','success'],
@@ -62,6 +62,7 @@ export default {
ruleForm:{ ruleForm:{
Id:editState.value.Id || 0, Id:editState.value.Id || 0,
Type:editState.value.Type || '',
UserId:editState.value.UserId || '', UserId:editState.value.UserId || '',
Name:editState.value.Name || '', Name:editState.value.Name || '',
Remark:editState.value.Remark || '', Remark:editState.value.Remark || '',
@@ -105,7 +106,7 @@ export default {
if (!valid) return; if (!valid) return;
const json = JSON.parse(JSON.stringify(state.ruleForm)); const json = JSON.parse(JSON.stringify(state.ruleForm));
user2NodeAdd(json).then(()=>{ wlistAdd(json).then(()=>{
ElMessage.success(t('common.oper')); ElMessage.success(t('common.oper'));
state.show = false; state.show = false;
emit('success'); emit('success');

View File

@@ -0,0 +1,36 @@
<template>
<a v-if="state.hasWhiteList && hasWhiteList" @click="state.showManager = true" href="javascript:;" class="mgr-1 a-line">{{$t('server.wlist')}}</a>
<Manager v-if="state.showManager" v-model="state.showManager" :type="state.type" />
</template>
<script>
import { injectGlobalData } from '@/provide';
import { computed, onMounted, reactive } from 'vue';
import Manager from './Manager.vue'
import { checkKey } from '@/apis/wlist';
export default {
props:['type'],
components:{Manager},
setup (props) {
const globalData = injectGlobalData();
const hasWhiteList = computed(()=>globalData.value.hasAccess('WhiteList'));
const state = reactive({
hasWhiteList:false,
showManager:false,
type:props.type
});
onMounted(()=>{
checkKey().then(res=>{
state.hasWhiteList = res;
}).catch(()=>{})
})
return {state,hasWhiteList}
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -1,11 +1,11 @@
<template> <template>
<el-dialog class="options-center" :title="$t('server.relayUser2Node')" destroy-on-close v-model="state.show" width="77rem" top="2vh"> <el-dialog class="options-center" :title="$t('server.wlist')" destroy-on-close v-model="state.show" width="77rem" top="2vh">
<div class="group-wrap"> <div class="group-wrap">
<div class="head"> <div class="head">
<div class="search flex"> <div class="search flex">
<div><span>{{$t('server.relayUser2NodeUserId')}}</span> <el-input v-model="state.page.UserId" style="width:8rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.wlistUserId')}}</span> <el-input v-model="state.page.UserId" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div><span>{{$t('server.relayUser2NodeName')}}</span> <el-input v-model="state.page.Name" style="width:8rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.wlistName')}}</span> <el-input v-model="state.page.Name" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div><span>{{$t('server.relayUser2NodeRemark')}}</span> <el-input v-model="state.page.Remark" style="width:8rem" size="small" clearable @change="handleSearch" /></div> <div><span>{{$t('server.wlistRemark')}}</span> <el-input v-model="state.page.Remark" style="width:8rem" size="small" clearable @change="handleSearch" /></div>
<div> <div>
<el-button size="small" @click="handleSearch()"> <el-button size="small" @click="handleSearch()">
<el-icon><Search /></el-icon> <el-icon><Search /></el-icon>
@@ -20,21 +20,21 @@
</div> </div>
<el-table stripe :data="state.list.List" border size="small" width="100%"> <el-table stripe :data="state.list.List" border size="small" width="100%">
<el-table-column prop="Name" :label="$t('server.relayUser2NodeName')"></el-table-column> <el-table-column prop="Name" :label="$t('server.wlistName')"></el-table-column>
<el-table-column prop="Nodes" :label="$t('server.relayUser2NodeNodes')"> <el-table-column prop="Nodes" :label="$t(`server.wlistNodes${state.page.Type}`)">
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.Nodes.map(c=>state.nodes[c]).join(',') }}</span> <span>{{ scope.row.Nodes.map(c=>state.nodes[c]).join(',') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="Remark" :label="$t('server.relayUser2NodeRemark')"></el-table-column> <el-table-column prop="Remark" :label="$t('server.wlistRemark')"></el-table-column>
<el-table-column prop="AddTime" :label="`${$t('server.relayUser2NodeAddTime')}`" width="140" sortable="custom"> <el-table-column prop="AddTime" :label="`${$t('server.wlistAddTime')}`" width="140" sortable="custom">
</el-table-column> </el-table-column>
<el-table-column fixed="right" prop="Oper" :label="$t('server.relayUser2NodeOper')" width="110"> <el-table-column fixed="right" prop="Oper" :label="$t('server.wlistOper')" width="110">
<template #default="scope"> <template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)"> <el-button size="small" @click="handleEdit(scope.row)">
<el-icon><EditPen /></el-icon> <el-icon><EditPen /></el-icon>
</el-button> </el-button>
<el-popconfirm :title="$t('server.relayUser2NodeDelConfirm')" @confirm="handleDel(scope.row)"> <el-popconfirm :title="$t('server.wlistDelConfirm')" @confirm="handleDel(scope.row)">
<template #reference> <template #reference>
<el-button type="danger" size="small"> <el-button type="danger" size="small">
<el-icon><Delete /></el-icon> <el-icon><Delete /></el-icon>
@@ -63,9 +63,9 @@ import { computed, inject, onMounted, provide, reactive, ref, watch } from 'vue'
import { Delete,Plus,Search,Warning,EditPen } from '@element-plus/icons-vue'; import { Delete,Plus,Search,Warning,EditPen } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import Add from './Add.vue'; import Add from './Add.vue';
import { user2NodeDel, user2NodePage } from '@/apis/relay'; import { wlistDel, wlistPage } from '@/apis/wlist';
export default { export default {
props: ['modelValue'], props: ['modelValue','type'],
emits: ['update:modelValue'], emits: ['update:modelValue'],
components:{Delete,Plus,Search ,EditPen,Add,Warning}, components:{Delete,Plus,Search ,EditPen,Add,Warning},
setup(props,{emit}) { setup(props,{emit}) {
@@ -76,6 +76,7 @@ export default {
page:{ page:{
Page:1, Page:1,
Size:10, Size:10,
Type:props.type,
UserId:'', UserId:'',
Name:'', Name:'',
Remark:'' Remark:''
@@ -103,7 +104,7 @@ export default {
provide('edit',editState); provide('edit',editState);
const handleAdd = ()=>{ const handleAdd = ()=>{
editState.value = {Id:0,Name:'',Nodes:[],Remark:'',UserId:''}; editState.value = {Id:0,Name:'',Nodes:[],Remark:'',UserId:'',Type:props.type};
state.showAdd = true; state.showAdd = true;
} }
const handleEdit = (row)=>{ const handleEdit = (row)=>{
@@ -111,7 +112,7 @@ export default {
state.showAdd = true; state.showAdd = true;
} }
const handleSearch = ()=>{ const handleSearch = ()=>{
user2NodePage(state.page).then((res)=>{ wlistPage(state.page).then((res)=>{
state.list = res; state.list = res;
}).catch(()=>{}) }).catch(()=>{})
} }
@@ -120,7 +121,7 @@ export default {
handleSearch(); handleSearch();
} }
const handleDel = (row)=>{ const handleDel = (row)=>{
user2NodeDel(row.Id).then((res)=>{ wlistDel(row.Id).then((res)=>{
handleSearch(); handleSearch();
}).catch(()=>{}) }).catch(()=>{})
} }

View File

@@ -45,6 +45,8 @@
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.server" :label="$t('status.exportServer')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.group" :label="$t('status.exportGroup')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.tunnel" :label="$t('status.exportTunnel')" /></el-col> <el-col :xs="12" :sm="8"><el-checkbox v-model="state.tunnel" :label="$t('status.exportTunnel')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.cdkey" :label="$t('status.exportCdkey')" /></el-col>
<el-col :xs="12" :sm="8"><el-checkbox v-model="state.whitelist" :label="$t('status.exportWhiteList')" /></el-col>
</el-row> </el-row>
</div> </div>
</div> </div>
@@ -115,6 +117,8 @@ export default {
server:true, server:true,
group:true, group:true,
tunnel:true, tunnel:true,
cdkey:true,
whitelist:true,
copyContent:'', copyContent:'',
showCopy:false, showCopy:false,
@@ -145,6 +149,8 @@ export default {
server:state.server, server:state.server,
group:state.group, group:state.group,
tunnel:state.tunnel, tunnel:state.tunnel,
cdkey:state.cdkey,
whitelist:state.whitelist,
} }
if(json.single){ if(json.single){

View File

@@ -1,5 +1,5 @@
v1.8.5 v1.8.5
2025-06-26 17:46:49 2025-07-01 01:13:22
1. 一些累计更新 1. 一些累计更新
2. 备用信标服务器 2. 备用信标服务器
3. 设置默认中继节点 3. 设置默认中继节点

View File

@@ -83,6 +83,7 @@ jobs:
dotnet pack ./src/linker.messenger.updater -c release dotnet pack ./src/linker.messenger.updater -c release
dotnet pack ./src/linker.messenger.firewall -c release dotnet pack ./src/linker.messenger.firewall -c release
dotnet pack ./src/linker.messenger.wakeup -c release dotnet pack ./src/linker.messenger.wakeup -c release
dotnet pack ./src/linker.messenger.wlist -c release
dotnet pack ./src/linker.tun -c release dotnet pack ./src/linker.tun -c release
dotnet pack ./src/linker.snat -c release dotnet pack ./src/linker.snat -c release
dotnet pack ./src/linker.tunnel -c release dotnet pack ./src/linker.tunnel -c release
@@ -117,6 +118,7 @@ jobs:
dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.firewall/bin/release/linker.messenger.firewall.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.firewall/bin/release/linker.messenger.firewall.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.wakeup/bin/release/linker.messenger.wakeup.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.messenger.wakeup/bin/release/linker.messenger.wakeup.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.wlist/bin/release/linker.messenger.wlist.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tun/bin/release/linker.tun.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.tun/bin/release/linker.tun.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.snat/bin/release/linker.snat.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.snat/bin/release/linker.snat.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.{{version}}.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols