commit
ee6a1ddb80
|
|
@ -0,0 +1,9 @@
|
|||
using BotSharp.Abstraction.Browsing.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Browsing;
|
||||
|
||||
public interface IWebPageResponseHook
|
||||
{
|
||||
void OnDataFetched(MessageInfo message, string url, string postData, string responsData);
|
||||
T? GetResponse<T>(MessageInfo message, string url);
|
||||
}
|
||||
|
|
@ -12,13 +12,6 @@ public class PageActionArgs
|
|||
public string Url { get; set; } = null!;
|
||||
public bool OpenNewTab { get; set; } = false;
|
||||
|
||||
public bool WaitForNetworkIdle = true;
|
||||
public bool WaitForNetworkIdle { get; set; } = true;
|
||||
public float? Timeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// On page data fetched
|
||||
/// </summary>
|
||||
public DataFetched? OnDataFetched { get; set; }
|
||||
}
|
||||
|
||||
public delegate void DataFetched(string url, string data);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ public interface IBotSharpRepository
|
|||
void UpdateUserVerified(string userId) => throw new NotImplementedException();
|
||||
void UpdateUserVerificationCode(string userId, string verficationCode) => throw new NotImplementedException();
|
||||
void UpdateUserPassword(string userId, string password) => throw new NotImplementedException();
|
||||
void UpdateUserEmail(string userId, string email)=> throw new NotImplementedException();
|
||||
void UpdateUserPhone(string userId, string Iphone) => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
#region Agent
|
||||
|
|
|
|||
|
|
@ -14,4 +14,6 @@ public interface IUserService
|
|||
Task<bool> VerifyEmailExisting(string email);
|
||||
Task<bool> SendVerificationCodeResetPassword(User user);
|
||||
Task<bool> ResetUserPassword(User user);
|
||||
Task<bool> ModifyUserEmail(string email);
|
||||
Task<bool> ModifyUserPhone(string phone);
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Aspects.Cache" Version="2.0.4" />
|
||||
<PackageReference Include="DistributedLock.Redis" Version="1.0.3" />
|
||||
<PackageReference Include="EntityFrameworkCore.BootKit" Version="8.4.2" />
|
||||
<PackageReference Include="EntityFrameworkCore.BootKit" Version="8.5.0" />
|
||||
<PackageReference Include="Fluid.Core" Version="2.8.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public static class BotSharpCoreExtensions
|
|||
services.AddScoped<IBotSharpRepository>(sp =>
|
||||
{
|
||||
var myDatabaseSettings = sp.GetRequiredService<BotSharpDatabaseSettings>();
|
||||
return DataContextHelper.GetDbContext<BotSharpDbContext, DbContext4SqlServer>(myDatabaseSettings, sp);
|
||||
return DataContextHelper.GetSqlServerDbContext<BotSharpDbContext>(myDatabaseSettings, sp);
|
||||
});
|
||||
|
||||
return services;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
using Microsoft.Data.SqlClient;
|
||||
using MySqlConnector;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace BotSharp.Core.Repository;
|
||||
|
||||
public static class DataContextHelper
|
||||
{
|
||||
public static T GetDbContext<T, Tdb>(BotSharpDatabaseSettings settings, IServiceProvider serviceProvider)
|
||||
public static T GetSqlServerDbContext<T>(BotSharpDatabaseSettings settings, IServiceProvider serviceProvider)
|
||||
where T : Database, new()
|
||||
where Tdb : DataContext
|
||||
{
|
||||
if (settings.Assemblies == null)
|
||||
throw new Exception("Please set assemblies.");
|
||||
|
|
@ -18,32 +16,40 @@ public static class DataContextHelper
|
|||
var dc = new T();
|
||||
if (typeof(T) == typeof(BotSharpDbContext))
|
||||
{
|
||||
if (typeof(Tdb).Name.StartsWith("DbContext4SqlServer"))
|
||||
dc.BindDbContext<IBotSharpTable, DbContext4SqlServer>(new DatabaseBind
|
||||
{
|
||||
dc.BindDbContext<IBotSharpTable, Tdb>(new DatabaseBind
|
||||
{
|
||||
ServiceProvider = serviceProvider,
|
||||
MasterConnection = new SqlConnection(settings.BotSharp.Master),
|
||||
SlaveConnections = settings.BotSharp.Slavers.Length == 0 ?
|
||||
new List<DbConnection> { new SqlConnection(settings.BotSharp.Master) } :
|
||||
settings.BotSharp.Slavers.Select(x => new SqlConnection(x) as DbConnection)
|
||||
.ToList(),
|
||||
CreateDbIfNotExist = true
|
||||
});
|
||||
}
|
||||
else if (typeof(Tdb).Name.StartsWith("DbContext4Aurora") ||
|
||||
typeof(Tdb).Name.StartsWith("DbContext4MySql"))
|
||||
{
|
||||
dc.BindDbContext<IBotSharpTable, Tdb>(new DatabaseBind
|
||||
{
|
||||
ServiceProvider = serviceProvider,
|
||||
MasterConnection = new MySqlConnection(settings.BotSharp.Master),
|
||||
SlaveConnections = settings.BotSharp.Slavers
|
||||
.Select(x => new MySqlConnection(x) as DbConnection).ToList(),
|
||||
CreateDbIfNotExist = true
|
||||
});
|
||||
}
|
||||
ServiceProvider = serviceProvider,
|
||||
MasterConnection = new SqlConnection(settings.BotSharp.Master),
|
||||
SlaveConnections = settings.BotSharp.Slavers.Length == 0 ?
|
||||
new List<DbConnection> { new SqlConnection(settings.BotSharp.Master) } :
|
||||
settings.BotSharp.Slavers.Select(x => new SqlConnection(x) as DbConnection)
|
||||
.ToList(),
|
||||
CreateDbIfNotExist = true
|
||||
});
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
/*public static T GetMySqlDbContext<T>(BotSharpDatabaseSettings settings, IServiceProvider serviceProvider)
|
||||
where T : Database, new()
|
||||
{
|
||||
if (settings.Assemblies == null)
|
||||
throw new Exception("Please set assemblies.");
|
||||
|
||||
AppDomain.CurrentDomain.SetData("Assemblies", settings.Assemblies);
|
||||
|
||||
var dc = new T();
|
||||
if (typeof(T) == typeof(BotSharpDbContext))
|
||||
{
|
||||
dc.BindDbContext<IBotSharpTable, DbContext4MySql>(new DatabaseBind
|
||||
{
|
||||
ServiceProvider = serviceProvider,
|
||||
MasterConnection = new MySqlConnection(settings.BotSharp.Master),
|
||||
SlaveConnections = settings.BotSharp.Slavers
|
||||
.Select(x => new MySqlConnection(x) as DbConnection).ToList(),
|
||||
CreateDbIfNotExist = true
|
||||
});
|
||||
}
|
||||
return dc;
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System.IO;
|
||||
using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using MongoDB.Driver;
|
||||
using System.Text.Encodings.Web;
|
||||
using BotSharp.Abstraction.Plugins.Models;
|
||||
using BotSharp.Abstraction.Statistics.Settings;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
using Amazon.SecurityToken.Model.Internal.MarshallTransformations;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Routing.Planning;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using System.Drawing;
|
||||
|
||||
namespace BotSharp.Core.Routing.Planning;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class UserIdentity : IUserIdentity
|
|||
|
||||
[JsonPropertyName("user_name")]
|
||||
public string UserName
|
||||
=> _claims?.FirstOrDefault(x => x.Type == "name")?.Value!;
|
||||
=> _claims?.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value!;
|
||||
|
||||
public string Email
|
||||
=> _claims?.FirstOrDefault(x => x.Type == ClaimTypes.Email)?.Value!;
|
||||
|
|
|
|||
|
|
@ -364,4 +364,33 @@ public class UserService : IUserService
|
|||
db.UpdateUserPassword(record.Id, newPassword);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> ModifyUserEmail(string email)
|
||||
{
|
||||
var curUser = await GetMyProfile();
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetUserById(curUser.Id);
|
||||
if (record == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
db.UpdateUserEmail(record.Id, email);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> ModifyUserPhone(string phone)
|
||||
{
|
||||
var curUser = await GetMyProfile();
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetUserById(curUser.Id);
|
||||
|
||||
if (record == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
db.UpdateUserPhone(record.Id, phone);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
using BotSharp.Abstraction.Loggers.Models;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using SharpCompress.Compressors.Xz;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,18 @@ public class UserController : ControllerBase
|
|||
return await _userService.ResetUserPassword(user.ToUser());
|
||||
}
|
||||
|
||||
[HttpPost("/user/email/modify")]
|
||||
public async Task<bool> ModifyUserEmail([FromQuery] string email)
|
||||
{
|
||||
return await _userService.ModifyUserEmail(email);
|
||||
}
|
||||
|
||||
[HttpPost("/user/phone/modify")]
|
||||
public async Task<bool> ModifyUserPhone([FromQuery] string phone)
|
||||
{
|
||||
return await _userService.ModifyUserPhone(phone);
|
||||
}
|
||||
|
||||
#region Avatar
|
||||
[HttpPost("/user/avatar")]
|
||||
public bool UploadUserAvatar([FromBody] BotSharpFile file)
|
||||
|
|
|
|||
|
|
@ -72,4 +72,20 @@ public partial class MongoRepository
|
|||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
public void UpdateUserEmail(string userId, string email)
|
||||
{
|
||||
var filter = Builders<UserDocument>.Filter.Eq(x => x.Id, userId);
|
||||
var update = Builders<UserDocument>.Update.Set(x => x.Email, email)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
public void UpdateUserPhone(string userId, string phone)
|
||||
{
|
||||
var filter = Builders<UserDocument>.Filter.Eq(x => x.Id, userId);
|
||||
var update = Builders<UserDocument>.Update.Set(x => x.Phone, phone)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using Amazon.Runtime.Internal.Transform;
|
||||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Core.Infrastructures;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.45.0" />
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.45.1" />
|
||||
<PackageReference Include="Selenium.WebDriver" Version="4.23.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -93,9 +93,9 @@ public class PlaywrightInstance : IDisposable
|
|||
return _contexts[ctxId];
|
||||
}
|
||||
|
||||
public async Task<IPage> NewPage(string ctxId, DataFetched? fetched)
|
||||
public async Task<IPage> NewPage(MessageInfo message, IServiceProvider services)
|
||||
{
|
||||
var context = await GetContext(ctxId);
|
||||
var context = await GetContext(message.ContextId);
|
||||
var page = await context.NewPageAsync();
|
||||
|
||||
// 许多网站为了防止信息被爬取,会添加一些防护手段。其中之一是检测 window.navigator.webdriver 属性。
|
||||
|
|
@ -103,35 +103,37 @@ public class PlaywrightInstance : IDisposable
|
|||
var js = @"Object.defineProperties(navigator, {webdriver:{get:()=>false}});";
|
||||
await page.AddInitScriptAsync(js);
|
||||
|
||||
if (fetched != null)
|
||||
page.Response += async (sender, e) =>
|
||||
{
|
||||
page.Response += async (sender, e) =>
|
||||
if (e.Headers.ContainsKey("content-type") &&
|
||||
e.Headers["content-type"].Contains("application/json") &&
|
||||
(e.Request.ResourceType == "fetch" || e.Request.ResourceType == "xhr"))
|
||||
{
|
||||
if (e.Headers.ContainsKey("content-type") &&
|
||||
e.Headers["content-type"].Contains("application/json") &&
|
||||
e.Request.ResourceType == "fetch")
|
||||
Serilog.Log.Information($"{e.Request.Method}: {e.Url}");
|
||||
JsonElement? json = null;
|
||||
try
|
||||
{
|
||||
Serilog.Log.Information($"fetched: {e.Url}");
|
||||
JsonElement? json = null;
|
||||
try
|
||||
if (e.Status == 200 && e.Ok)
|
||||
{
|
||||
if (e.Status == 200 && e.Ok)
|
||||
{
|
||||
json = await e.JsonAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serilog.Log.Warning($"Response status: {e.Status} {e.StatusText}, OK: {e.Ok}");
|
||||
}
|
||||
fetched(e.Url.ToLower(), JsonSerializer.Serialize(json));
|
||||
json = await e.JsonAsync();
|
||||
}
|
||||
catch(Exception ex)
|
||||
else
|
||||
{
|
||||
Serilog.Log.Error(ex.ToString());
|
||||
Serilog.Log.Warning($"Response status: {e.Status} {e.StatusText}, OK: {e.Ok}");
|
||||
}
|
||||
|
||||
var webPageResponseHooks = services.GetServices<IWebPageResponseHook>();
|
||||
foreach (var hook in webPageResponseHooks)
|
||||
{
|
||||
hook.OnDataFetched(message, e.Url.ToLower(), e.Request?.PostData ?? string.Empty, JsonSerializer.Serialize(json));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Serilog.Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return page;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
|
||||
|
||||
public partial class PlaywrightWebDriver
|
||||
|
|
@ -26,7 +24,7 @@ public partial class PlaywrightWebDriver
|
|||
}
|
||||
}*/
|
||||
|
||||
var page = args.OpenNewTab ? await _instance.NewPage(message.ContextId, fetched: args.OnDataFetched) :
|
||||
var page = args.OpenNewTab ? await _instance.NewPage(message, _services) :
|
||||
_instance.GetPage(message.ContextId);
|
||||
|
||||
Serilog.Log.Information($"goto page: {args.Url}");
|
||||
|
|
@ -64,14 +62,4 @@ public partial class PlaywrightWebDriver
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Page_Response1(object sender, IResponse e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void Page_Response(object sender, IResponse e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue