mirror of
https://github.com/snltty/linker.git
synced 2025-12-24 12:38:04 +08:00
很多修改
This commit is contained in:
2
.github/workflows/dotnet.yml
vendored
2
.github/workflows/dotnet.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
release_name: v1.9.7.${{ steps.date.outputs.today }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: "1. 一些累计更新,一些BUG修复\r\n2. 重构中继和穿透的多节点模式\r\n3. 中继连接合并到隧道协议中\r\n4. 修复socks代理模块\r\n5. 发布飞牛fpk安装包(docker+bin)\r\n6. 先不要更新,作者测试中"
|
||||
body: "1. 一些累计更新,一些BUG修复\r\n2. 重构中继和穿透的多节点模式\r\n3. 中继连接合并到隧道协议中\r\n4. 修复socks代理模块\r\n5. 发布飞牛fpk安装包(docker+bin)\r\n6. 优化虚拟网卡自动连接表现\r\n7. 简化加入分组操作\r\n8. 先不要更新,作者测试中"
|
||||
- name: setup node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
|
||||
@@ -1,15 +1,41 @@
|
||||
namespace linker.messenger.node
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.node
|
||||
{
|
||||
/// <summary>
|
||||
/// 禁用的主机
|
||||
/// </summary>
|
||||
public interface INodeMasterDenyStore
|
||||
{
|
||||
public Task<MasterDenyStoreResponseInfo> Get(MasterDenyStoreRequestInfo request);
|
||||
public Task<bool> Get(uint ip);
|
||||
public Task<bool> Add(string str);
|
||||
public Task<bool> Delete(int id);
|
||||
public Task<bool> Get(uint ip,int plus);
|
||||
public Task<bool> Add(MasterDenyAddInfo info);
|
||||
public Task<bool> Delete(MasterDenyDelInfo info);
|
||||
}
|
||||
|
||||
public sealed class MastersRequestInfo
|
||||
{
|
||||
public string NodeId { get; set; }
|
||||
public int Page { get; set; }
|
||||
public int Sise { get; set; }
|
||||
}
|
||||
public sealed class MastersResponseInfo
|
||||
{
|
||||
public int Page { get; set; }
|
||||
public int Sise { get; set; }
|
||||
public int Count { get; set; }
|
||||
public List<MasterConnInfo> List { get; set; } = new List<MasterConnInfo>();
|
||||
}
|
||||
public sealed class MasterConnInfo
|
||||
{
|
||||
public IPEndPoint Addr { get; set; }
|
||||
public string NodeId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public sealed class MasterDenyStoreRequestInfo
|
||||
{
|
||||
public string NodeId { get; set; }
|
||||
public int Page { get; set; }
|
||||
public int Sise { get; set; }
|
||||
public string Str { get; set; }
|
||||
@@ -27,6 +53,20 @@
|
||||
public uint Ip { get; set; }
|
||||
public uint Plus { get; set; }
|
||||
public string Str { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public sealed class MasterDenyAddInfo
|
||||
{
|
||||
public string NodeId { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string Str { get; set; }
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
public sealed class MasterDenyDelInfo
|
||||
{
|
||||
public string NodeId { get; set; }
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,10 @@ namespace linker.messenger.node
|
||||
public virtual ushort MessengerIdExitForward { get; }
|
||||
public virtual ushort MessengerIdReport { get; }
|
||||
public virtual ushort MessengerIdSignIn { get; }
|
||||
public virtual ushort MessengerIdMastersForward { get; }
|
||||
public virtual ushort MessengerIdDenysForward { get; }
|
||||
public virtual ushort MessengerIdDenysAddForward { get; }
|
||||
public virtual ushort MessengerIdDenysDelForward { get; }
|
||||
|
||||
|
||||
private int connectionNum = 0;
|
||||
@@ -36,10 +40,11 @@ namespace linker.messenger.node
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly INodeStore<TStore, TReport> nodeStore;
|
||||
private readonly IMessengerResolver messengerResolver;
|
||||
private readonly INodeMasterDenyStore nodeMasterDenyStore;
|
||||
|
||||
public NodeReportTransfer(NodeConnectionTransfer nodeConnectionTransfer, INodeConfigStore<TConfig> nodeConfigStore,
|
||||
ISerializer serializer, IMessengerSender messengerSender, INodeStore<TStore, TReport> nodeStore,
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore)
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore, INodeMasterDenyStore nodeMasterDenyStore)
|
||||
{
|
||||
this.nodeConnectionTransfer = nodeConnectionTransfer;
|
||||
this.nodeConfigStore = nodeConfigStore;
|
||||
@@ -47,6 +52,7 @@ namespace linker.messenger.node
|
||||
this.messengerSender = messengerSender;
|
||||
this.nodeStore = nodeStore;
|
||||
this.messengerResolver = messengerResolver;
|
||||
this.nodeMasterDenyStore = nodeMasterDenyStore;
|
||||
|
||||
md5 = Config.NodeId.Md5();
|
||||
|
||||
@@ -97,6 +103,10 @@ namespace linker.messenger.node
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (await nodeMasterDenyStore.Get(NetworkHelper.ToValue(connection.Address.Address), 0).ConfigureAwait(false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
connection.Id = serverId;
|
||||
nodeConnectionTransfer.TryAdd(ConnectionSideType.Master, connection.Id, connection);
|
||||
@@ -116,7 +126,7 @@ namespace linker.messenger.node
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdSahre,
|
||||
Payload = serializer.Serialize(store.MasterKey)
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<string>(resp.Data.Span);
|
||||
@@ -172,7 +182,7 @@ namespace linker.messenger.node
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdUpdateForward,
|
||||
Payload = serializer.Serialize(info)
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return await nodeStore.Update(info).ConfigureAwait(false);
|
||||
@@ -192,7 +202,7 @@ namespace linker.messenger.node
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdUpgradeForward,
|
||||
Payload = serializer.Serialize(new KeyValuePair<string, string>(store.MasterKey, version))
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -209,7 +219,6 @@ namespace linker.messenger.node
|
||||
public async Task<bool> ExitForward(string nodeId)
|
||||
{
|
||||
TStore store = await nodeStore.GetByNodeId(nodeId);
|
||||
|
||||
if (store != null && store.Manageable && nodeConnectionTransfer.TryGet(ConnectionSideType.Node, nodeId, out var connection))
|
||||
{
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
@@ -217,7 +226,7 @@ namespace linker.messenger.node
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdExitForward,
|
||||
Payload = serializer.Serialize(new KeyValuePair<string, string>(store.MasterKey, nodeId))
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -232,11 +241,123 @@ namespace linker.messenger.node
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点列表
|
||||
/// </summary>
|
||||
/// <param name="super">是否已认证</param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task<MastersResponseInfo> MastersForward(MastersRequestInfo info)
|
||||
{
|
||||
TStore store = await nodeStore.GetByNodeId(info.NodeId);
|
||||
if (store != null && store.Manageable && nodeConnectionTransfer.TryGet(ConnectionSideType.Node, info.NodeId, out var connection))
|
||||
{
|
||||
info.NodeId = store.MasterKey;
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdMastersForward,
|
||||
Payload = serializer.Serialize(info)
|
||||
}).ConfigureAwait(false);
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MastersResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
}
|
||||
|
||||
return new MastersResponseInfo();
|
||||
}
|
||||
public async Task<MastersResponseInfo> Masters(MastersRequestInfo info)
|
||||
{
|
||||
if (info.NodeId != Config.MasterKey)
|
||||
{
|
||||
return new MastersResponseInfo();
|
||||
}
|
||||
|
||||
var connections = nodeConnectionTransfer.Get(ConnectionSideType.Master);
|
||||
return new MastersResponseInfo
|
||||
{
|
||||
Page = info.Page,
|
||||
Sise = info.Sise,
|
||||
Count = connections.Count,
|
||||
List = connections.Skip((info.Page - 1) * info.Sise).Take(info.Sise).Select(c => new MasterConnInfo { Addr = c.Address, NodeId = c.Id }).ToList()
|
||||
};
|
||||
}
|
||||
public async Task<MasterDenyStoreResponseInfo> DenysForward(MasterDenyStoreRequestInfo info)
|
||||
{
|
||||
TStore store = await nodeStore.GetByNodeId(info.NodeId);
|
||||
if (store != null && store.Manageable && nodeConnectionTransfer.TryGet(ConnectionSideType.Node, info.NodeId, out var connection))
|
||||
{
|
||||
info.NodeId = store.MasterKey;
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdDenysForward,
|
||||
Payload = serializer.Serialize(info)
|
||||
}).ConfigureAwait(false);
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MasterDenyStoreResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
}
|
||||
|
||||
return new MasterDenyStoreResponseInfo();
|
||||
}
|
||||
public async Task<MasterDenyStoreResponseInfo> Denys(MasterDenyStoreRequestInfo info)
|
||||
{
|
||||
if (info.NodeId != Config.MasterKey)
|
||||
{
|
||||
return new MasterDenyStoreResponseInfo();
|
||||
}
|
||||
return await nodeMasterDenyStore.Get(info).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<bool> DenysAddForward(MasterDenyAddInfo info)
|
||||
{
|
||||
TStore store = await nodeStore.GetByNodeId(info.NodeId);
|
||||
if (store != null && store.Manageable && nodeConnectionTransfer.TryGet(ConnectionSideType.Node, info.NodeId, out var connection))
|
||||
{
|
||||
info.NodeId = store.MasterKey;
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdDenysAddForward,
|
||||
Payload = serializer.Serialize(info)
|
||||
}).ConfigureAwait(false);
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public async Task<bool> DenysAdd(MasterDenyAddInfo info)
|
||||
{
|
||||
if (info.NodeId != Config.MasterKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return await nodeMasterDenyStore.Add(info).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<bool> DenysDelForward(MasterDenyDelInfo info)
|
||||
{
|
||||
TStore store = await nodeStore.GetByNodeId(info.NodeId);
|
||||
if (store != null && store.Manageable && nodeConnectionTransfer.TryGet(ConnectionSideType.Node, info.NodeId, out var connection))
|
||||
{
|
||||
info.NodeId = store.MasterKey;
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = connection,
|
||||
MessengerId = MessengerIdDenysDelForward,
|
||||
Payload = serializer.Serialize(info)
|
||||
}).ConfigureAwait(false);
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public async Task<bool> DenysDel(MasterDenyDelInfo info)
|
||||
{
|
||||
if (info.NodeId != Config.MasterKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return await nodeMasterDenyStore.Delete(info).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<List<TStore>> GetNodes(bool super, string userid, string machineId)
|
||||
{
|
||||
return [];
|
||||
@@ -256,7 +377,6 @@ namespace linker.messenger.node
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private async Task BuildShareKey()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
v1.9.7
|
||||
2025-12-10 17:13:38
|
||||
2025-12-11 17:30:06
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 重构中继和穿透的多节点模式
|
||||
3. 中继连接合并到隧道协议中
|
||||
4. 修复socks代理模块
|
||||
5. 发布飞牛fpk安装包(docker+bin)
|
||||
6. 先不要更新,作者测试中
|
||||
6. 优化虚拟网卡自动连接表现
|
||||
7. 简化加入分组操作
|
||||
8. 先不要更新,作者测试中
|
||||
@@ -18,7 +18,7 @@ slug: /question
|
||||
3. `Windows 无法验证此文件的数字签名`,大概率出现再win7/8,可以尝试安装<a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=46148" target="_blank">KB3033929 全球化补丁</a>
|
||||
4. `group id are empty` 客户端尚未初始化
|
||||
5. `rtsp`,关于rtsp,默认使用UDP协议传输音视频,在rtsp握手的SETUP阶段报告客户端UDP端口,所以在经过NAT后服务端无法正确向客户端发送数据,请使用TCP
|
||||
6. 在windows,如果1802-1804端口被占用,但是`netstat -ano` 又查不到,那可能是hyper-v占用的可以尝试重启winnat服务解决
|
||||
6. 在windows,如果1802-1804端口被占用,但是`netstat -ano` 又查不到,那可能是hyper-v占用的,可以尝试重启winnat服务解决
|
||||
```
|
||||
net stop winnat
|
||||
net start winnat
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.web;
|
||||
using linker.messenger.node;
|
||||
using linker.messenger.relay.messenger;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.signin;
|
||||
@@ -130,6 +131,55 @@ namespace linker.messenger.relay.client
|
||||
});
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
|
||||
public async Task<MastersResponseInfo> Masters(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)RelayMessengerIds.MastersForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MastersRequestInfo>())
|
||||
});
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MastersResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
return new MastersResponseInfo();
|
||||
}
|
||||
public async Task<MasterDenyStoreResponseInfo> Denys(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)RelayMessengerIds.DenysForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyStoreRequestInfo>())
|
||||
});
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MasterDenyStoreResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
return new MasterDenyStoreResponseInfo();
|
||||
}
|
||||
public async Task<bool> DenysAdd(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)RelayMessengerIds.DenysAddForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyAddInfo>())
|
||||
});
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
public async Task<bool> DenysDel(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)RelayMessengerIds.DenysDelForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyDelInfo>())
|
||||
});
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
using linker.libs;
|
||||
using linker.messenger.node;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.relay.server.validator;
|
||||
using linker.messenger.signin;
|
||||
@@ -16,7 +17,7 @@ namespace linker.messenger.relay.messenger
|
||||
public RelayClientMessenger()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -230,6 +231,91 @@ namespace linker.messenger.relay.messenger
|
||||
}
|
||||
|
||||
|
||||
|
||||
[MessengerId((ushort)RelayMessengerIds.MastersForward)]
|
||||
public async Task MastersForward(IConnection connection)
|
||||
{
|
||||
MastersRequestInfo info = serializer.Deserialize<MastersRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new MastersResponseInfo()));
|
||||
return;
|
||||
}
|
||||
|
||||
MastersResponseInfo resp = await relayServerNodeReportTransfer.MastersForward(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.Masters)]
|
||||
public async Task Masters(IConnection connection)
|
||||
{
|
||||
MastersRequestInfo info = serializer.Deserialize<MastersRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
MastersResponseInfo resp = await relayServerNodeReportTransfer.Masters(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
|
||||
|
||||
[MessengerId((ushort)RelayMessengerIds.DenysForward)]
|
||||
public async Task DenysForward(IConnection connection)
|
||||
{
|
||||
MasterDenyStoreRequestInfo info = serializer.Deserialize<MasterDenyStoreRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new MasterDenyStoreResponseInfo()));
|
||||
return;
|
||||
}
|
||||
|
||||
MasterDenyStoreResponseInfo resp = await relayServerNodeReportTransfer.DenysForward(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.Denys)]
|
||||
public async Task Denys(IConnection connection)
|
||||
{
|
||||
MasterDenyStoreRequestInfo info = serializer.Deserialize<MasterDenyStoreRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
MasterDenyStoreResponseInfo resp = await relayServerNodeReportTransfer.Denys(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.DenysAddForward)]
|
||||
public async Task DenysAddForward(IConnection connection)
|
||||
{
|
||||
MasterDenyAddInfo info = serializer.Deserialize<MasterDenyAddInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(Helper.FalseArray);
|
||||
return;
|
||||
}
|
||||
|
||||
bool resp = await relayServerNodeReportTransfer.DenysAddForward(info).ConfigureAwait(false);
|
||||
connection.Write(resp ? Helper.TrueArray : Helper.FalseArray);
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.DenysAdd)]
|
||||
public async Task DenysAdd(IConnection connection)
|
||||
{
|
||||
MasterDenyAddInfo info = serializer.Deserialize<MasterDenyAddInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
bool resp = await relayServerNodeReportTransfer.DenysAdd(info).ConfigureAwait(false);
|
||||
connection.Write(resp ? Helper.TrueArray : Helper.FalseArray);
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.DenysDelForward)]
|
||||
public async Task DenysDelForward(IConnection connection)
|
||||
{
|
||||
MasterDenyDelInfo info = serializer.Deserialize<MasterDenyDelInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(Helper.FalseArray);
|
||||
return;
|
||||
}
|
||||
|
||||
bool resp = await relayServerNodeReportTransfer.DenysDelForward(info).ConfigureAwait(false);
|
||||
connection.Write(resp ? Helper.TrueArray : Helper.FalseArray);
|
||||
}
|
||||
[MessengerId((ushort)RelayMessengerIds.DenysDel)]
|
||||
public async Task DenysDel(IConnection connection)
|
||||
{
|
||||
MasterDenyDelInfo info = serializer.Deserialize<MasterDenyDelInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
bool resp = await relayServerNodeReportTransfer.DenysDel(info).ConfigureAwait(false);
|
||||
connection.Write(resp ? Helper.TrueArray : Helper.FalseArray);
|
||||
}
|
||||
|
||||
|
||||
[MessengerId((ushort)RelayMessengerIds.NodeReport)]
|
||||
public async Task NodeReport(IConnection connection)
|
||||
{
|
||||
@@ -251,5 +337,9 @@ namespace linker.messenger.relay.messenger
|
||||
}
|
||||
connection.Write(serializer.Serialize(VersionHelper.Version));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,16 @@
|
||||
UpgradeForward = 2144,
|
||||
Upgrade = 2145,
|
||||
|
||||
MastersForward = 2146,
|
||||
Masters = 2147,
|
||||
|
||||
DenysForward = 2148,
|
||||
Denys = 2149,
|
||||
DenysAddForward = 2150,
|
||||
DenysAdd = 2151,
|
||||
DenysDelForward = 2152,
|
||||
DenysDel = 2153,
|
||||
|
||||
Max = 2199
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using linker.messenger.node;
|
||||
|
||||
namespace linker.messenger.relay.server
|
||||
{
|
||||
public interface IRelayServerMasterDenyStore:INodeMasterDenyStore
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,10 @@ namespace linker.messenger.relay.server
|
||||
public override ushort MessengerIdExitForward => (ushort)RelayMessengerIds.ExitForward;
|
||||
public override ushort MessengerIdReport => (ushort)RelayMessengerIds.Report;
|
||||
public override ushort MessengerIdSignIn => (ushort)RelayMessengerIds.SignIn;
|
||||
public override ushort MessengerIdMastersForward => (ushort)RelayMessengerIds.MastersForward;
|
||||
public override ushort MessengerIdDenysForward => (ushort)RelayMessengerIds.DenysForward;
|
||||
public override ushort MessengerIdDenysAddForward => (ushort)RelayMessengerIds.DenysAddForward;
|
||||
public override ushort MessengerIdDenysDelForward => (ushort)RelayMessengerIds.DenysDelForward;
|
||||
|
||||
private readonly IRelayServerWhiteListStore relayServerWhiteListStore;
|
||||
private readonly INodeConfigStore<RelayServerConfigInfo> nodeConfigStore;
|
||||
@@ -21,8 +25,8 @@ namespace linker.messenger.relay.server
|
||||
public RelayServerNodeReportTransfer(IRelayServerWhiteListStore relayServerWhiteListStore, RelayServerConnectionTransfer nodeConnectionTransfer,
|
||||
INodeConfigStore<RelayServerConfigInfo> nodeConfigStore,
|
||||
ISerializer serializer, IMessengerSender messengerSender, INodeStore<RelayServerNodeStoreInfo, RelayServerNodeReportInfo> nodeStore,
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore)
|
||||
: base(nodeConnectionTransfer, nodeConfigStore, serializer, messengerSender, nodeStore, messengerResolver, commonStore)
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore,IRelayServerMasterDenyStore relayServerMasterDenyStore)
|
||||
: base(nodeConnectionTransfer, nodeConfigStore, serializer, messengerSender, nodeStore, messengerResolver, commonStore, relayServerMasterDenyStore)
|
||||
{
|
||||
this.relayServerWhiteListStore = relayServerWhiteListStore;
|
||||
this.nodeConfigStore = nodeConfigStore;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using linker.libs.extends;
|
||||
using linker.messenger.signin;
|
||||
using linker.libs;
|
||||
using linker.messenger.api;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.web;
|
||||
using linker.messenger.sforward.server;
|
||||
using linker.messenger.api;
|
||||
using linker.messenger.node;
|
||||
using linker.messenger.sforward.messenger;
|
||||
using linker.messenger.sforward.server;
|
||||
using linker.messenger.signin;
|
||||
|
||||
namespace linker.messenger.sforward.client
|
||||
{
|
||||
@@ -236,5 +237,54 @@ namespace linker.messenger.sforward.client
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
|
||||
|
||||
public async Task<MastersResponseInfo> Masters(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)SForwardMessengerIds.MastersForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MastersRequestInfo>())
|
||||
});
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MastersResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
return new MastersResponseInfo();
|
||||
}
|
||||
public async Task<MasterDenyStoreResponseInfo> Denys(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)SForwardMessengerIds.DenysForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyStoreRequestInfo>())
|
||||
});
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
return serializer.Deserialize<MasterDenyStoreResponseInfo>(resp.Data.Span);
|
||||
}
|
||||
return new MasterDenyStoreResponseInfo();
|
||||
}
|
||||
public async Task<bool> DenysAdd(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)SForwardMessengerIds.DenysAddForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyAddInfo>())
|
||||
});
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
public async Task<bool> DenysDel(ApiControllerParamsInfo param)
|
||||
{
|
||||
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)SForwardMessengerIds.DenysDelForward,
|
||||
Payload = serializer.Serialize(param.Content.DeJson<MasterDenyDelInfo>())
|
||||
});
|
||||
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.node;
|
||||
using linker.messenger.sforward.client;
|
||||
using linker.messenger.sforward.server;
|
||||
using linker.messenger.sforward.server.validator;
|
||||
@@ -695,6 +696,68 @@ namespace linker.messenger.sforward.messenger
|
||||
await sForwardServerNodeReportTransfer.Exit(masterKey).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信标服务器
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
/// <returns></returns>
|
||||
[MessengerId((ushort)SForwardMessengerIds.MastersForward)]
|
||||
public async Task MastersForward(IConnection connection)
|
||||
{
|
||||
MastersRequestInfo info = serializer.Deserialize<MastersRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new MastersResponseInfo()));
|
||||
return;
|
||||
}
|
||||
|
||||
MastersResponseInfo resp = await sForwardServerNodeReportTransfer.MastersForward(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
/// <summary>
|
||||
/// 节点服务器
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
/// <returns></returns>
|
||||
[MessengerId((ushort)SForwardMessengerIds.Masters)]
|
||||
public async Task Masters(IConnection connection)
|
||||
{
|
||||
MastersRequestInfo info = serializer.Deserialize<MastersRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
MastersResponseInfo resp = await sForwardServerNodeReportTransfer.Masters(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信标服务器
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
/// <returns></returns>
|
||||
[MessengerId((ushort)SForwardMessengerIds.DenysForward)]
|
||||
public async Task DenysForward(IConnection connection)
|
||||
{
|
||||
MasterDenyStoreRequestInfo info = serializer.Deserialize<MasterDenyStoreRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo from) == false || from.Super == false)
|
||||
{
|
||||
connection.Write(serializer.Serialize(new MasterDenyStoreResponseInfo()));
|
||||
return;
|
||||
}
|
||||
|
||||
MasterDenyStoreResponseInfo resp = await sForwardServerNodeReportTransfer.DenysForward(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
/// <summary>
|
||||
/// 节点服务器
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
/// <returns></returns>
|
||||
[MessengerId((ushort)SForwardMessengerIds.Denys)]
|
||||
public async Task Denys(IConnection connection)
|
||||
{
|
||||
MasterDenyStoreRequestInfo info = serializer.Deserialize<MasterDenyStoreRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
MasterDenyStoreResponseInfo resp = await sForwardServerNodeReportTransfer.Denys(info).ConfigureAwait(false);
|
||||
connection.Write(serializer.Serialize(resp));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -50,6 +50,16 @@
|
||||
Proxy = 2352,
|
||||
ProxyForward = 2353,
|
||||
|
||||
MastersForward = 2354,
|
||||
Masters = 2355,
|
||||
|
||||
DenysForward = 2356,
|
||||
Denys = 2357,
|
||||
DenysAddForward = 2358,
|
||||
DenysAdd = 2359,
|
||||
DenysDelForward = 2360,
|
||||
DenysDel = 2361,
|
||||
|
||||
Max = 2399
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using linker.messenger.node;
|
||||
|
||||
namespace linker.messenger.sforward.server
|
||||
{
|
||||
public interface ISForwardServerMasterDenyStore : INodeMasterDenyStore
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -12,17 +12,20 @@ namespace linker.messenger.sforward.server
|
||||
public override ushort MessengerIdExitForward => (ushort)SForwardMessengerIds.ExitForward;
|
||||
public override ushort MessengerIdReport => (ushort)SForwardMessengerIds.Report;
|
||||
public override ushort MessengerIdSignIn => (ushort)SForwardMessengerIds.SignIn;
|
||||
public override ushort MessengerIdMastersForward => (ushort)SForwardMessengerIds.MastersForward;
|
||||
public override ushort MessengerIdDenysForward => (ushort)SForwardMessengerIds.DenysForward;
|
||||
public override ushort MessengerIdDenysAddForward => (ushort)SForwardMessengerIds.DenysAddForward;
|
||||
public override ushort MessengerIdDenysDelForward => (ushort)SForwardMessengerIds.DenysDelForward;
|
||||
|
||||
private readonly ISForwardServerWhiteListStore sforwardServerWhiteListStore;
|
||||
private readonly INodeConfigStore<SForwardServerConfigInfo> nodeConfigStore;
|
||||
private readonly INodeStore<SForwardServerNodeStoreInfo, SForwardServerNodeReportInfo> nodeStore;
|
||||
|
||||
|
||||
public SForwardServerNodeReportTransfer(ISForwardServerWhiteListStore sforwardServerWhiteListStore, SForwardServerConnectionTransfer nodeConnectionTransfer,
|
||||
INodeConfigStore<SForwardServerConfigInfo> nodeConfigStore,
|
||||
ISerializer serializer, IMessengerSender messengerSender, INodeStore<SForwardServerNodeStoreInfo, SForwardServerNodeReportInfo> nodeStore,
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore)
|
||||
: base(nodeConnectionTransfer, nodeConfigStore, serializer, messengerSender, nodeStore, messengerResolver, commonStore)
|
||||
IMessengerResolver messengerResolver, ICommonStore commonStore,ISForwardServerMasterDenyStore sforwardServerMasterDenyStore)
|
||||
: base(nodeConnectionTransfer, nodeConfigStore, serializer, messengerSender, nodeStore, messengerResolver, commonStore, sforwardServerMasterDenyStore)
|
||||
{
|
||||
this.sforwardServerWhiteListStore = sforwardServerWhiteListStore;
|
||||
this.nodeConfigStore = nodeConfigStore;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace linker.messenger.signin
|
||||
#if DEBUG
|
||||
private string id = Helper.GlobalString;
|
||||
#else
|
||||
private string id = string.Empty;
|
||||
private string id = Guid.NewGuid().ToString();
|
||||
#endif
|
||||
public string Id
|
||||
{
|
||||
@@ -25,7 +25,7 @@ namespace linker.messenger.signin
|
||||
#if DEBUG
|
||||
private string passord = Helper.GlobalString;
|
||||
#else
|
||||
private string passord = string.Empty;
|
||||
private string passord = Guid.NewGuid().ToString();
|
||||
#endif
|
||||
public string Password
|
||||
{
|
||||
|
||||
@@ -157,8 +157,12 @@ namespace linker.messenger.signin
|
||||
{
|
||||
await signInClientTransfer.CheckSuper().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public sealed class ConfigSetInfo
|
||||
{
|
||||
|
||||
@@ -20,9 +20,10 @@ namespace linker.messenger.signin
|
||||
private readonly SignInArgsTransfer signInArgsTransfer;
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
private readonly ISerializer serializer;
|
||||
private readonly ICommonStore commonStore;
|
||||
|
||||
public SignInClientTransfer(SignInClientState clientSignInState, IMessengerSender messengerSender, IMessengerResolver messengerResolver,
|
||||
SignInArgsTransfer signInArgsTransfer, ISignInClientStore signInClientStore, ISerializer serializer)
|
||||
SignInArgsTransfer signInArgsTransfer, ISignInClientStore signInClientStore, ISerializer serializer, ICommonStore commonStore)
|
||||
{
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.messengerSender = messengerSender;
|
||||
@@ -30,6 +31,7 @@ namespace linker.messenger.signin
|
||||
this.signInArgsTransfer = signInArgsTransfer;
|
||||
this.signInClientStore = signInClientStore;
|
||||
this.serializer = serializer;
|
||||
this.commonStore = commonStore;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,6 +107,11 @@ namespace linker.messenger.signin
|
||||
/// <returns></returns>
|
||||
private async Task<int> SignIn(string host)
|
||||
{
|
||||
if(commonStore.Installed == false)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"not initialized");
|
||||
return 1;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(signInClientStore.Group.Id))
|
||||
{
|
||||
LoggerHelper.Instance.Error($"group id are empty");
|
||||
|
||||
@@ -56,7 +56,5 @@ namespace linker.messenger.signin.args
|
||||
}
|
||||
return await Task.FromResult(string.Empty);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ namespace linker.messenger.store.file
|
||||
config.Data.Server.SignIn.Anonymous = info.Server.Anonymous;
|
||||
config.Data.Server.SignIn.SuperKey = info.Server.SuperKey;
|
||||
config.Data.Server.SignIn.SuperPassword = info.Server.SuperPassword;
|
||||
config.Data.Server.SForward.WebPort = info.Server.SForward.WebPort;
|
||||
config.Data.Server.SForward.TunnelPorts = info.Server.SForward.TunnelPorts;
|
||||
//config.Data.Server.SForward.WebPort = info.Server.SForward.WebPort;
|
||||
//config.Data.Server.SForward.TunnelPorts = info.Server.SForward.TunnelPorts;
|
||||
}
|
||||
|
||||
config.Data.Common.Modes = info.Common.Modes;
|
||||
@@ -300,6 +300,61 @@ namespace linker.messenger.store.file
|
||||
}, common, new { Install = true, Modes = new string[] { "client" } });
|
||||
}
|
||||
|
||||
[Access(AccessValue.Export)]
|
||||
public string ShareGroup(ApiControllerParamsInfo param)
|
||||
{
|
||||
ICrypto crypto = CryptoFactory.CreateSymmetric(Helper.GlobalString);
|
||||
|
||||
try
|
||||
{
|
||||
return Convert.ToBase64String(crypto.Encode(new ShareGroupInfo
|
||||
{
|
||||
Server = config.Data.Client.Server.Host,
|
||||
Id = config.Data.Client.Group.Id,
|
||||
Pwd = config.Data.Client.Group.Password
|
||||
}.ToJson().ToBytes()));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
crypto.Dispose();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public bool JoinGroup(ApiControllerParamsInfo param)
|
||||
{
|
||||
ICrypto crypto = CryptoFactory.CreateSymmetric(Helper.GlobalString);
|
||||
|
||||
try
|
||||
{
|
||||
ShareGroupInfo info = crypto.Decode(Convert.FromBase64String(param.Content)).GetString().DeJson<ShareGroupInfo>();
|
||||
config.Data.Client.Server.Host = info.Server;
|
||||
config.Data.Client.Group.Id = info.Id;
|
||||
config.Data.Client.Group.Password = info.Pwd;
|
||||
config.Data.Update();
|
||||
|
||||
signInClientTransfer.ReSignIn();
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
crypto.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ShareGroupInfo
|
||||
{
|
||||
public string Server { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Pwd { get; set; }
|
||||
}
|
||||
|
||||
public sealed class GetConfigParamsInfo
|
||||
|
||||
@@ -73,7 +73,8 @@ namespace linker.messenger.store.file
|
||||
serviceCollection.AddSingleton<INodeConfigStore<RelayServerConfigInfo>, RelayServerConfigStore>();
|
||||
serviceCollection.AddSingleton<INodeStore<RelayServerNodeStoreInfo, RelayServerNodeReportInfo>, RelayServerNodeStore>();
|
||||
serviceCollection.AddSingleton<IRelayServerWhiteListStore, RelayNodeWhiteListStore>();
|
||||
|
||||
serviceCollection.AddSingleton<IRelayServerMasterDenyStore, RelayServerMasterDenyStore>();
|
||||
|
||||
|
||||
serviceCollection.AddSingleton<ITunnelClientStore, TunnelClientStore>();
|
||||
|
||||
@@ -101,6 +102,7 @@ namespace linker.messenger.store.file
|
||||
serviceCollection.AddSingleton<INodeConfigStore<SForwardServerConfigInfo>, SForwardServerConfigStore>();
|
||||
serviceCollection.AddSingleton<INodeStore<SForwardServerNodeStoreInfo, SForwardServerNodeReportInfo>, SForwardServerNodeStore>();
|
||||
serviceCollection.AddSingleton<ISForwardServerWhiteListStore, SForwardNodeWhiteListStore>();
|
||||
serviceCollection.AddSingleton<ISForwardServerMasterDenyStore, SForwardServerMasterDenyStore>();
|
||||
|
||||
serviceCollection.AddSingleton<ILoggerStore, LoggerStore>();
|
||||
|
||||
|
||||
63
src/linker.messenger.store.file/node/NodeMasterDenyStore.cs
Normal file
63
src/linker.messenger.store.file/node/NodeMasterDenyStore.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using linker.libs;
|
||||
using linker.messenger.node;
|
||||
using LiteDB;
|
||||
using System.Net;
|
||||
using IPNetwork = System.Net.IPNetwork;
|
||||
|
||||
namespace linker.messenger.store.file.node
|
||||
{
|
||||
public class NodeMasterDenyStore : INodeMasterDenyStore
|
||||
{
|
||||
public virtual string StoreName => "relay";
|
||||
|
||||
protected readonly ILiteCollection<MasterDenyStoreInfo> liteCollection;
|
||||
public NodeMasterDenyStore(Storefactory storefactory)
|
||||
{
|
||||
liteCollection = storefactory.GetCollection<MasterDenyStoreInfo>($"{StoreName}_server_master_deny");
|
||||
}
|
||||
|
||||
public async Task<bool> Add(MasterDenyAddInfo info)
|
||||
{
|
||||
IPNetwork net = info.Str.AsSpan().IndexOf('/') < 0 ? new IPNetwork(IPAddress.Parse(info.Str), 32) : IPNetwork.Parse(info.Str);
|
||||
|
||||
uint ip = NetworkHelper.ToValue(net.BaseAddress);
|
||||
uint prefixValue = NetworkHelper.ToPrefixValue((byte)net.PrefixLength);
|
||||
uint network = NetworkHelper.ToNetworkValue(ip, prefixValue);
|
||||
uint broadcast = NetworkHelper.ToBroadcastValue(ip, prefixValue);
|
||||
liteCollection.Insert(new MasterDenyStoreInfo
|
||||
{
|
||||
Str = info.Str,
|
||||
Ip = ip,
|
||||
Plus = broadcast - network,
|
||||
Remark = info.Remark,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> Delete(MasterDenyDelInfo info)
|
||||
{
|
||||
return liteCollection.Delete(info.Id);
|
||||
}
|
||||
|
||||
public async Task<MasterDenyStoreResponseInfo> Get(MasterDenyStoreRequestInfo request)
|
||||
{
|
||||
var query = liteCollection.FindAll();
|
||||
if (string.IsNullOrWhiteSpace(request.Str) == false)
|
||||
{
|
||||
query = query.Where(c => (string.IsNullOrWhiteSpace(c.Str) == false && c.Str.Contains(request.Str)) || string.IsNullOrWhiteSpace(c.Remark) == false && c.Remark.Contains(request.Str));
|
||||
}
|
||||
return new MasterDenyStoreResponseInfo
|
||||
{
|
||||
Page = request.Page,
|
||||
Sise = request.Sise,
|
||||
Count = query.Count(),
|
||||
List = query.Skip((request.Page - 1) * request.Sise).Take(request.Sise).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<bool> Get(uint ip, int plus)
|
||||
{
|
||||
return liteCollection.Find(c => ip >= c.Ip && ip <= c.Ip + c.Plus).Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,9 @@ namespace linker.messenger.store.file.relay
|
||||
{
|
||||
public class RelayNodeWhiteListStore : node.NodeWhiteListStore, IRelayServerWhiteListStore
|
||||
{
|
||||
public override string TypeName => "Relay";
|
||||
public RelayNodeWhiteListStore(IWhiteListServerStore whiteListServerStore) : base(whiteListServerStore) { }
|
||||
|
||||
public override string TypeName => "Relay";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.store.file.node;
|
||||
|
||||
namespace linker.messenger.store.file.relay
|
||||
{
|
||||
public class RelayServerMasterDenyStore : NodeMasterDenyStore, IRelayServerMasterDenyStore
|
||||
{
|
||||
public override string StoreName => "relay";
|
||||
public RelayServerMasterDenyStore(Storefactory storefactory) : base(storefactory)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,9 @@ namespace linker.messenger.store.file.sforward
|
||||
{
|
||||
public class SForwardNodeWhiteListStore : node.NodeWhiteListStore, ISForwardServerWhiteListStore
|
||||
{
|
||||
public override string TypeName => "SForward";
|
||||
public SForwardNodeWhiteListStore(IWhiteListServerStore whiteListServerStore) : base(whiteListServerStore) { }
|
||||
|
||||
public override string TypeName => "SForward";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using linker.messenger.sforward.server;
|
||||
using linker.messenger.store.file.node;
|
||||
|
||||
namespace linker.messenger.store.file.sforward
|
||||
{
|
||||
public class SForwardServerMasterDenyStore : NodeMasterDenyStore, ISForwardServerMasterDenyStore
|
||||
{
|
||||
public override string StoreName => "sforward";
|
||||
public SForwardServerMasterDenyStore(Storefactory storefactory) :base(storefactory)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using linker.libs.extends;
|
||||
using linker.messenger.node;
|
||||
using linker.messenger.relay.server;
|
||||
using linker.messenger.sforward.server;
|
||||
using linker.messenger.store.file.node;
|
||||
using LiteDB;
|
||||
|
||||
namespace linker.messenger.store.file.sforward
|
||||
{
|
||||
|
||||
@@ -21,4 +21,10 @@ export const copyConfig = (data) => {
|
||||
}
|
||||
export const saveConfig = (data) => {
|
||||
return sendWebsocketMsg('config/save', data);
|
||||
}
|
||||
export const shareGroup = () => {
|
||||
return sendWebsocketMsg('config/sharegroup');
|
||||
}
|
||||
export const joinGroup = (data) => {
|
||||
return sendWebsocketMsg('config/joingroup', data);
|
||||
}
|
||||
@@ -29,4 +29,16 @@ export const relayImport = (data) => {
|
||||
}
|
||||
export const relayShare = (id) => {
|
||||
return sendWebsocketMsg('relay/Share', id);
|
||||
}
|
||||
export const relayMasters = (data) => {
|
||||
return sendWebsocketMsg('relay/Masters', data);
|
||||
}
|
||||
export const relayDenys = (data) => {
|
||||
return sendWebsocketMsg('relay/Denys', data);
|
||||
}
|
||||
export const relayDenysAdd = (data) => {
|
||||
return sendWebsocketMsg('relay/DenysAdd', data);
|
||||
}
|
||||
export const relayDenysDel = (data) => {
|
||||
return sendWebsocketMsg('relay/DenysDel', data);
|
||||
}
|
||||
@@ -44,4 +44,16 @@ export const sforwardImport = (data) => {
|
||||
}
|
||||
export const sforwardShare = (id) => {
|
||||
return sendWebsocketMsg('sforward/Share', id);
|
||||
}
|
||||
export const sforwardMasters = (data) => {
|
||||
return sendWebsocketMsg('sforward/Masters', data);
|
||||
}
|
||||
export const sforwardDenys = (data) => {
|
||||
return sendWebsocketMsg('sforward/Denys', data);
|
||||
}
|
||||
export const sforwardDenysAdd = (data) => {
|
||||
return sendWebsocketMsg('sforward/DenysAdd', data);
|
||||
}
|
||||
export const sforwardDenysDel = (data) => {
|
||||
return sendWebsocketMsg('sforward/DenysDel', data);
|
||||
}
|
||||
@@ -11,6 +11,7 @@ export default {
|
||||
'common.relay': 'Relay',
|
||||
'common.p2p': 'P2P',
|
||||
'common.refresh': 'Refresh',
|
||||
'common.copied': 'Copied',
|
||||
|
||||
'head.home': 'Home',
|
||||
'head.server': 'Server',
|
||||
@@ -85,6 +86,8 @@ export default {
|
||||
'permission.clear': 'Clear connection',
|
||||
|
||||
'status.group': 'Group manager',
|
||||
'status.groupShare': 'Group share',
|
||||
'status.groupPlus': 'Group join',
|
||||
'status.groupName': 'Name',
|
||||
'status.groupPassword': 'Password',
|
||||
'status.groupOper': 'Oper',
|
||||
@@ -349,6 +352,10 @@ export default {
|
||||
'server.sforwardLogo': 'Logo',
|
||||
'server.sforwardHost': 'Host',
|
||||
|
||||
'server.denyTitle':'connections on 【{0}】',
|
||||
'server.denyMasters':'Online',
|
||||
'server.denyList':'Deny list',
|
||||
|
||||
'server.updater':'Updater',
|
||||
'server.updaterSecretKey': 'Server update secretKey',
|
||||
'server.updaterSync2Server': 'Auto update to server version',
|
||||
|
||||
@@ -11,6 +11,7 @@ export default {
|
||||
'common.relay': '中继',
|
||||
'common.p2p': '打洞',
|
||||
'common.refresh': '刷新',
|
||||
'common.copied': '已复制',
|
||||
|
||||
'head.home': '首页',
|
||||
'head.server': '服务器',
|
||||
@@ -86,6 +87,8 @@ export default {
|
||||
'permission.clear': '清除连接',
|
||||
|
||||
'status.group': '管理分组',
|
||||
'status.groupShare': '分享分组',
|
||||
'status.groupPlus': '加入分组',
|
||||
'status.groupName': '名称',
|
||||
'status.groupPassword': '密码',
|
||||
'status.groupOper': '操作',
|
||||
@@ -440,6 +443,10 @@ export default {
|
||||
'server.sforwardLogo': 'Logo',
|
||||
'server.sforwardHost': '主机',
|
||||
|
||||
'server.denyTitle':'【{0}】上的主机',
|
||||
'server.denyMasters':'在线的主机',
|
||||
'server.denyList':'禁用列表',
|
||||
|
||||
'server.updater': '更新',
|
||||
'server.updaterSecretKey': '服务器更新密钥',
|
||||
'server.updaterSync2Server': '自动更新到服务器版本',
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="flex">
|
||||
<el-badge @click.stop type="success" :value="scope.row.MasterCount" :offset="[20, 10]">
|
||||
<el-badge @click="handleDeny(scope.row)" type="success" :value="scope.row.MasterCount" :offset="[20, 10]">
|
||||
<a :href="scope.row.Url" class="a-line" target="_blank">
|
||||
<strong>{{ scope.row.Name }}</strong>
|
||||
</a>
|
||||
@@ -112,6 +112,7 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
<EditNode v-if="state.showEdit" v-model="state.showEdit" :data="state.current"></EditNode>
|
||||
<NodeDeny v-model="state.showDeny" v-if="state.showDeny" type="sforward" :data="state.current"></NodeDeny>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -122,11 +123,11 @@ import { computed, onUnmounted, reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import EditNode from './EditNode.vue';
|
||||
import { Edit,ArrowDown,Refresh,CircleClose,Plus,Share } from '@element-plus/icons-vue';
|
||||
|
||||
import NodeDeny from '../node/Index.vue'
|
||||
export default {
|
||||
props: ['modelValue','data'],
|
||||
emits: ['update:modelValue','success'],
|
||||
components:{EditNode,Edit,ArrowDown,Refresh,CircleClose,Plus,Share},
|
||||
components:{EditNode,Edit,ArrowDown,Refresh,CircleClose,Plus,Share,NodeDeny},
|
||||
setup(props,{emit}) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
@@ -136,7 +137,9 @@ export default {
|
||||
showEdit:false,
|
||||
current:{},
|
||||
|
||||
super:computed(()=>globalData.value.signin.Super)
|
||||
super:computed(()=>globalData.value.signin.Super),
|
||||
|
||||
showDeny:false
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
@@ -228,11 +231,16 @@ export default {
|
||||
});
|
||||
}
|
||||
|
||||
const handleDeny = (row)=>{
|
||||
state.current = row;
|
||||
state.showDeny = true;
|
||||
}
|
||||
|
||||
onUnmounted(()=>{
|
||||
clearTimeout(state.timer);
|
||||
});
|
||||
|
||||
return {globalData,state,handleEdit,handleExit,handleUpgrade,handleRemove,handleImport,handleShare}
|
||||
return {globalData,state,handleEdit,handleExit,handleUpgrade,handleRemove,handleImport,handleShare,handleDeny}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
<el-icon class="right"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<AccessShow value="Group">
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="item in state.groups" @click="handleGroupChange(item.Id)">{{item.Name || '未知'}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="state.showGroups = true">{{$t('status.group')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</AccessShow>
|
||||
<el-dropdown-menu>
|
||||
<AccessShow value="Group">
|
||||
<el-dropdown-item v-for="item in state.groups" @click="handleGroupChange(item.Id)">{{item.Name || '未知'}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleGroups"><el-icon><Setting /></el-icon>{{$t('status.group')}}</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleShare"><el-icon><Share /></el-icon>{{$t('status.groupShare')}}</el-dropdown-item>
|
||||
</AccessShow>
|
||||
<el-dropdown-item @click="handleJoin"><el-icon><Plus /></el-icon>{{$t('status.groupPlus')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<Groups v-if="state.showGroups" v-model="state.showGroups"></Groups>
|
||||
@@ -19,13 +21,14 @@
|
||||
<script>
|
||||
import { setSignIn } from '@/apis/signin';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import {ArrowDown,Avatar} from '@element-plus/icons-vue'
|
||||
import {ArrowDown,Avatar,Setting,Share,Plus} from '@element-plus/icons-vue'
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Groups from './Groups.vue';
|
||||
import { joinGroup, shareGroup } from '@/apis/config';
|
||||
export default {
|
||||
components:{ArrowDown,Avatar,Groups},
|
||||
components:{ArrowDown,Avatar,Groups,Setting,Share,Plus},
|
||||
props:['config'],
|
||||
setup(props) {
|
||||
const { t } = useI18n();
|
||||
@@ -66,8 +69,45 @@ export default {
|
||||
ElMessage.error(t('common.operFail'));
|
||||
});
|
||||
}
|
||||
|
||||
const handleGroups = ()=>{
|
||||
state.showGroups = true;
|
||||
}
|
||||
const handleShare = ()=>{
|
||||
shareGroup().then((res)=>{
|
||||
if(res){
|
||||
navigator.clipboard.writeText(res);
|
||||
ElMessage.success(t('common.copied'));
|
||||
}else{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
}
|
||||
}).catch(()=>{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
})
|
||||
}
|
||||
const handleJoin = ()=>{
|
||||
ElMessageBox.prompt(t('status.groupPlus'), t('common.tips'), {
|
||||
confirmButtonText: t('common.confirm'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
}).then(({ value }) => {
|
||||
joinGroup(value).then((res)=>{
|
||||
if(res){
|
||||
ElMessage.success(t('common.oper'));
|
||||
setTimeout(()=>{
|
||||
window.location.reload();
|
||||
},1000);
|
||||
}else{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
}
|
||||
}).catch(()=>{
|
||||
ElMessage.error(t('common.operFail'));
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
config:props.config,state,handleGroupChange
|
||||
state,handleGroupChange,handleGroups,handleShare,handleJoin
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +120,7 @@ export default {
|
||||
color:green;font-weight:bold;
|
||||
}
|
||||
.el-icon{
|
||||
vertical-align:bottom;
|
||||
vertical-align:top;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
src/linker.web/src/views/components/node/Denys.vue
Normal file
20
src/linker.web/src/views/components/node/Denys.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['type','data'],
|
||||
setup () {
|
||||
|
||||
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
</style>
|
||||
39
src/linker.web/src/views/components/node/Index.vue
Normal file
39
src/linker.web/src/views/components/node/Index.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<el-dialog v-model="state.show" :title="$t('server.denyTitle',[data.Name])" top="1vh" width="400">
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane :label="$t('server.denyMasters')"><Masters :type="type" :data="data"></Masters></el-tab-pane>
|
||||
<el-tab-pane :label="$t('server.denyList')"><Denys :type="type" :data="data"></Denys></el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive, watch } from 'vue';
|
||||
import Masters from './Masters.vue';
|
||||
import Denys from './Denys.vue';
|
||||
export default {
|
||||
props: ['type','data','modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
components: {Masters,Denys},
|
||||
setup (props,{emit}) {
|
||||
const state = reactive({
|
||||
show: true
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
setTimeout(() => {
|
||||
emit('update:modelValue', val);
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
return {state}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
</style>
|
||||
70
src/linker.web/src/views/components/node/Masters.vue
Normal file
70
src/linker.web/src/views/components/node/Masters.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-table :data="state.request.List" stripe border size="small" width="100%">
|
||||
<el-table-column prop="Addr" label="IP"></el-table-column>
|
||||
</el-table>
|
||||
<div class="page t-c">
|
||||
<div class="page-wrap">
|
||||
<el-pagination small background layout="total,prev,pager, next" :total="state.request.Count"
|
||||
:page-size="state.request.Size" :current-page="state.request.Page" @current-change="handlePageChange"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { relayMasters } from '@/apis/relay';
|
||||
import { sforwardMasters } from '@/apis/sforward';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
|
||||
export default {
|
||||
props: ['type','data'],
|
||||
setup (props,{emit}) {
|
||||
|
||||
const getDataFn = props.type == 'relay' ? relayMasters : sforwardMasters;
|
||||
const state = reactive({
|
||||
request:{
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
Count:0,
|
||||
List:[]
|
||||
}
|
||||
});
|
||||
|
||||
const getData = ()=>{
|
||||
getDataFn(state.request).then(res=>{
|
||||
state.request.Page = res.Page;
|
||||
state.request.Size = res.Size;
|
||||
state.request.Count = res.Count;
|
||||
state.request.List = res.List;
|
||||
})
|
||||
}
|
||||
|
||||
const handlePageChange = (page)=>{
|
||||
if (page) {
|
||||
state.request.Page = page;
|
||||
}
|
||||
getData();
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
getData();
|
||||
});
|
||||
|
||||
|
||||
return {state,handlePageChange}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.head{
|
||||
padding-bottom:1rem;
|
||||
text-align:center;
|
||||
.el-input{width:20rem}
|
||||
}
|
||||
.page{padding-top:1rem}
|
||||
.page-wrap{
|
||||
display:inline-block;
|
||||
}
|
||||
</style>
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="flex">
|
||||
<el-badge @click.stop type="success" :value="scope.row.MasterCount" :offset="[20, 10]">
|
||||
<el-badge @click="handleDeny(scope.row)" type="success" :value="scope.row.MasterCount" :offset="[20, 10]">
|
||||
<a :href="scope.row.Url" class="a-line" :class="{green:scope.row.Public}" target="_blank" >
|
||||
<strong>{{ scope.row.Name }}</strong>
|
||||
</a>
|
||||
@@ -128,6 +128,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<NodeDeny v-model="state.showDeny" v-if="state.showDeny" type="relay" :data="state.current"></NodeDeny>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -139,11 +140,11 @@ import { useI18n } from 'vue-i18n';
|
||||
import Ids from '../sync/Ids.vue';
|
||||
import EditNode from './EditNode.vue';
|
||||
import { Edit,ArrowDown,Refresh,CircleClose,Plus,Share } from '@element-plus/icons-vue';
|
||||
|
||||
import NodeDeny from '../node/Index.vue'
|
||||
export default {
|
||||
props: ['modelValue','data'],
|
||||
emits: ['update:modelValue','success'],
|
||||
components:{Ids,EditNode,Edit,ArrowDown,Refresh,CircleClose,Plus,Share},
|
||||
components:{Ids,EditNode,Edit,ArrowDown,Refresh,CircleClose,Plus,Share,NodeDeny},
|
||||
setup(props,{emit}) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
@@ -158,7 +159,9 @@ export default {
|
||||
Key:'',
|
||||
Value:0
|
||||
},
|
||||
super:computed(()=>globalData.value.signin.Super)
|
||||
super:computed(()=>globalData.value.signin.Super),
|
||||
|
||||
showDeny:false
|
||||
});
|
||||
watch(() => state.show, (val) => {
|
||||
if (!val) {
|
||||
@@ -280,6 +283,10 @@ export default {
|
||||
ElMessage.error(t('common.operFail'));
|
||||
});
|
||||
}
|
||||
const handleDeny = (row)=>{
|
||||
state.current = row;
|
||||
state.showDeny = true;
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
_getDefault();
|
||||
@@ -290,7 +297,7 @@ export default {
|
||||
|
||||
return {globalData,state,
|
||||
handleEdit,domIds,handleShowSync,handleSync,handleCancelSync,
|
||||
handleExit,handleUpgrade,handleRemove,handleImport,handleShare}
|
||||
handleExit,handleUpgrade,handleRemove,handleImport,handleShare,handleDeny}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:title="$t('status.apiAlterConfirm')" @cancel="handleShow" @confirm="handleResetConnect" >
|
||||
<template #reference>
|
||||
<a href="javascript:;">
|
||||
<el-icon size="16"><Tools /></el-icon>
|
||||
<el-icon size="16"><Flag /></el-icon>
|
||||
<span>{{$t('status.api')}}</span>
|
||||
</a>
|
||||
</template>
|
||||
@@ -17,9 +17,9 @@
|
||||
import {injectGlobalData} from '@/provide'
|
||||
import { computed} from 'vue';
|
||||
import { initWebsocket,closeWebsocket } from '@/apis/request'
|
||||
import {Tools} from '@element-plus/icons-vue'
|
||||
import {Flag} from '@element-plus/icons-vue'
|
||||
export default {
|
||||
components:{Tools},
|
||||
components:{Flag},
|
||||
props:['config'],
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<template>
|
||||
<div class="status-wrap flex">
|
||||
<div class="copy flex">
|
||||
<a href="javascript:;" class="memory" :title="$t('status.support')" @click="state.showPay = true">
|
||||
<!-- <a href="https://afdian.com/a/snltty" class="memory" :title="$t('status.support')" target="_blank"> -->
|
||||
<img src="@/assets/dianchi.svg" alt="memory" />
|
||||
<span>{{$t('status.support')}}</span>
|
||||
</a>
|
||||
<Support></Support>
|
||||
<a href="javascript:;">©linker {{ self.Version }}</a>
|
||||
<PcShow>
|
||||
<a href="https://github.com/snltty/linker" target="_blank">Github</a>
|
||||
@@ -14,46 +10,27 @@
|
||||
</PcShow>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<div class="export"><Export :config="config"></Export></div>
|
||||
<PcShow>
|
||||
<div class="api"><Api :config="config"></Api></div>
|
||||
</PcShow>
|
||||
<div class="server"><Server :config="config"></Server></div>
|
||||
|
||||
<el-dialog v-model="state.showPay" :title="$t('status.support')" width="80%">
|
||||
<div class="pay">
|
||||
<p class="t-c">
|
||||
<a href="https://afdian.com/a/snltty" class="memory a-line" :title="$t('status.support')" target="_blank">
|
||||
<img src="@/assets/dianchi.svg" alt="memory" />
|
||||
<span>{{$t('status.support')}}</span>
|
||||
</a>
|
||||
</p>
|
||||
<p class="t-c">
|
||||
OR
|
||||
</p>
|
||||
<p>
|
||||
<img src="@/assets/pay.jpg" alt="pay" width="100%"/>
|
||||
</p>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, reactive } from 'vue';
|
||||
import Api from './Api.vue'
|
||||
import Server from './server/Index.vue'
|
||||
import Export from './Export.vue'
|
||||
import UpdaterBtn from '../updater/UpdaterBtn.vue';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import Support from './Support.vue';
|
||||
export default {
|
||||
components:{Api,Server,Export,UpdaterBtn},
|
||||
components:{Api,Server,UpdaterBtn,Support},
|
||||
props:['config'],
|
||||
setup(props) {
|
||||
const globalData = injectGlobalData();
|
||||
const self = computed(()=>globalData.value.self);
|
||||
|
||||
const state = reactive({
|
||||
showPay:false
|
||||
});
|
||||
return {
|
||||
state,config:props.config,self
|
||||
@@ -78,9 +55,6 @@ html.dark .status-wrap .copy a{color:#ccc;}
|
||||
a{color:#555;margin-right:1rem}
|
||||
}
|
||||
|
||||
a.memory{
|
||||
img{height:2rem;vertical-align:sub;margin-right:.1rem;}
|
||||
margin-right:.6rem;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
42
src/linker.web/src/views/components/status/Support.vue
Normal file
42
src/linker.web/src/views/components/status/Support.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<a href="javascript:;" class="memory" :title="$t('status.support')" @click="state.showPay = true">
|
||||
<img src="@/assets/dianchi.svg" alt="memory" />
|
||||
<span>{{$t('status.support')}}</span>
|
||||
</a>
|
||||
<el-dialog v-model="state.showPay" :title="$t('status.support')" width="80%">
|
||||
<div class="pay">
|
||||
<p class="t-c">
|
||||
<a href="https://afdian.com/a/snltty" class="memory a-line" :title="$t('status.support')" target="_blank">
|
||||
<img src="@/assets/dianchi.svg" alt="memory" />
|
||||
<span>{{$t('status.support')}}</span>
|
||||
</a>
|
||||
</p>
|
||||
<p class="t-c">
|
||||
OR
|
||||
</p>
|
||||
<p>
|
||||
<img src="@/assets/pay.jpg" alt="pay" width="100%"/>
|
||||
</p>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
|
||||
export default {
|
||||
setup () {
|
||||
const state = reactive({
|
||||
showPay:false
|
||||
});
|
||||
return {state}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
a.memory{
|
||||
img{height:2rem;vertical-align:sub;margin-right:.1rem;}
|
||||
margin-right:.6rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div class="signin-wrap" :style="{height:`${state.height}px`}">
|
||||
<el-card shadow="never">
|
||||
<template #header>{{$t('server.messenger')}}</template>
|
||||
<template #header>
|
||||
<div class="flex">
|
||||
<span>{{$t('server.messenger')}}</span>
|
||||
<span class="flex-1"></span>
|
||||
<Export></Export>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<el-form label-width="auto" :label-position="state.position">
|
||||
<el-form-item :label="$t('server.messengerAddr')">
|
||||
@@ -68,9 +74,9 @@ import SForwardServers from '../../../components/forward/Config.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Sync from '../../../components/sync/Index.vue'
|
||||
import WhiteList from '../../../components/wlist/Index.vue';
|
||||
|
||||
import Export from './Export.vue';
|
||||
export default {
|
||||
components:{Updater,RelayServers,SForwardServers,Sync,WhiteList},
|
||||
components:{Updater,RelayServers,SForwardServers,Sync,WhiteList,Export},
|
||||
setup(props) {
|
||||
const {t} = useI18n();
|
||||
const globalData = injectGlobalData();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<AccessShow value="Export">
|
||||
<div v-if="config" class="status-export-wrap">
|
||||
<a href="javascript:;" :title="$t('status.export')" @click="state.show = true">
|
||||
<div class="status-export-wrap">
|
||||
<a href="javascript:;" class="a-line" :title="$t('status.export')" @click="state.show = true">
|
||||
<el-icon size="16"><Share /></el-icon>
|
||||
<PcShow>
|
||||
<span>{{$t('status.export')}}</span>
|
||||
@@ -93,11 +93,10 @@ import {Share} from '@element-plus/icons-vue'
|
||||
import { exportConfig,copyConfig,saveConfig } from '@/apis/config';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { injectGlobalData } from '@/provide';
|
||||
import Access from '../accesss/Access.vue'
|
||||
import Access from '../../../components/accesss/Access.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
export default {
|
||||
components:{Share,Access},
|
||||
props:['config'],
|
||||
setup(props) {
|
||||
|
||||
const { t } = useI18n();
|
||||
@@ -257,7 +256,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
return {globalData,config:props.config,onlyNode, state,accessDom,
|
||||
return {globalData,onlyNode, state,accessDom,
|
||||
handleSave,handleExport,handleCopy,copyToClipboard,copySaveToClipboard};
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,13 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="web穿透端口" prop="webPort">
|
||||
<el-input v-trim v-model="state.form.webPort" />
|
||||
</el-form-item>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="匿名登录" prop="anonymous">
|
||||
<el-checkbox v-model="state.form.anonymous">匿名登录</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="穿透端口" prop="TunnelPorts">
|
||||
<el-input v-trim v-model="state.form.TunnelPorts" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" label-width="0">
|
||||
<el-row>
|
||||
@@ -32,18 +31,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="" label-width="0">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="匿名登录" prop="anonymous">
|
||||
<el-checkbox v-model="state.form.anonymous">匿名登录</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
3. 中继连接合并到隧道协议中
|
||||
4. 修复socks代理模块
|
||||
5. 发布飞牛fpk安装包(docker+bin)
|
||||
6. 先不要更新,作者测试中</Description>
|
||||
6. 优化虚拟网卡自动连接表现
|
||||
7. 简化加入分组操作
|
||||
8. 先不要更新,作者测试中</Description>
|
||||
<Copyright>snltty</Copyright>
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
|
||||
Reference in New Issue
Block a user