Merge pull request #685 from Qtoss-AI/master

Miscellaneous improvements
This commit is contained in:
Haiping 2024-10-14 17:45:11 -05:00 committed by GitHub
commit 331b931d2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 115 additions and 20 deletions

View file

@ -8,6 +8,7 @@ public interface IAuthenticationHook
Task<User> Authenticate(string id, string password);
void AddClaims(List<Claim> claims);
void BeforeSending(Token token);
Task UserUpdating(User user);
Task UserCreated(User user);
Task VerificationCodeResetPassword(User user);
Task DelUsers(List<string> userIds);

View file

@ -8,7 +8,10 @@ public interface IUserIdentity
string FirstName { get; }
string LastName { get; }
string FullName { get; }
string? UserLanguage { get; }
/// <summary>
/// "en-US", "zh-CN"
/// </summary>
string UserLanguage { get; }
string? Phone { get; }
string? AffiliateId { get; }
}

View file

@ -13,6 +13,7 @@ public interface IUserService
Task<User> GetMyProfile();
Task<bool> VerifyUserNameExisting(string userName);
Task<bool> VerifyEmailExisting(string email);
Task<bool> VerifyPhoneExisting(string phone);
Task<bool> SendVerificationCodeResetPasswordNoLogin(User user);
Task<bool> SendVerificationCodeResetPasswordLogin();
Task<bool> ResetUserPassword(User user);

View file

@ -4,7 +4,7 @@ namespace BotSharp.Core.Infrastructures;
public static class HookEmitter
{
public static async Task<HookEmittedResult> Emit<T>(IServiceProvider services, Action<T> action)
public static HookEmittedResult Emit<T>(IServiceProvider services, Action<T> action)
{
var logger = services.GetRequiredService<ILogger<T>>();
var result = new HookEmittedResult();
@ -25,4 +25,26 @@ public static class HookEmitter
return result;
}
public static async Task<HookEmittedResult> Emit<T>(IServiceProvider services, Func<T, Task> action)
{
var logger = services.GetRequiredService<ILogger<T>>();
var result = new HookEmittedResult();
var hooks = services.GetServices<T>();
foreach (var hook in hooks)
{
try
{
logger.LogInformation($"Emit hook action on {action.Method.Name}({hook.GetType().Name})");
await action(hook);
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
return result;
}
}

View file

@ -58,12 +58,12 @@ public class UserIdentity : IUserIdentity
}
[JsonPropertyName("user_language")]
public string? UserLanguage
public string UserLanguage
{
get
{
_contextAccessor.HttpContext.Request.Headers.TryGetValue("User-Language", out var languages);
return languages.FirstOrDefault();
return languages.FirstOrDefault() ?? "en-US";
}
}

View file

@ -33,7 +33,7 @@ public class UserService : IUserService
public async Task<User> CreateUser(User user)
{
string hasRegisterId = null;
if (string.IsNullOrEmpty(user.UserName))
if (string.IsNullOrWhiteSpace(user.UserName))
{
// generate unique name
var name = Nanoid.Generate("0123456789botsharp", 10);
@ -45,16 +45,46 @@ public class UserService : IUserService
}
var db = _services.GetRequiredService<IBotSharpRepository>();
var record = db.GetUserByUserName(user.UserName);
User? record = null;
if (!string.IsNullOrWhiteSpace(user.UserName))
{
record = db.GetUserByUserName(user.UserName);
}
if (record != null && record.Verified)
{
// account is already activated
_logger.LogWarning($"User account already exists: {record.Id} {record.UserName}");
return record;
}
if (!string.IsNullOrWhiteSpace(user.Phone))
{
record = db.GetUserByPhone(user.Phone);
}
if (record == null && !string.IsNullOrWhiteSpace(user.Email))
{
record = db.GetUserByEmail(user.Email);
}
if (record != null)
{
hasRegisterId = record.Id;
}
if (string.IsNullOrEmpty(user.Id))
if (string.IsNullOrWhiteSpace(user.Id))
{
user.Id = Guid.NewGuid().ToString();
if (!string.IsNullOrWhiteSpace(hasRegisterId))
{
user.Id = hasRegisterId;
}
else
{
user.Id = Guid.NewGuid().ToString();
}
}
record = user;
@ -68,7 +98,7 @@ public class UserService : IUserService
if (_setting.NewUserVerification)
{
record.VerificationCode = Nanoid.Generate(alphabet: "0123456789", size: 6);
// record.VerificationCode = Nanoid.Generate(alphabet: "0123456789", size: 6);
record.Verified = false;
}
@ -421,6 +451,23 @@ public class UserService : IUserService
return false;
}
public async Task<bool> VerifyPhoneExisting(string phone)
{
if (string.IsNullOrEmpty(phone))
{
return true;
}
var db = _services.GetRequiredService<IBotSharpRepository>();
var UserByphone = db.GetUserByPhone(phone);
if (UserByphone != null && UserByphone.Verified)
{
return true;
}
return false;
}
public async Task<bool> SendVerificationCodeResetPasswordNoLogin(User user)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
@ -456,7 +503,7 @@ public class UserService : IUserService
var hooks = _services.GetServices<IAuthenticationHook>();
foreach (var hook in hooks)
{
hook.VerificationCodeResetPassword(record);
await hook.VerificationCodeResetPassword(record);
}
return true;
@ -487,7 +534,7 @@ public class UserService : IUserService
var hooks = _services.GetServices<IAuthenticationHook>();
foreach (var hook in hooks)
{
hook.VerificationCodeResetPassword(record);
await hook.VerificationCodeResetPassword(record);
}
return true;
@ -533,12 +580,20 @@ public class UserService : IUserService
var curUser = await GetMyProfile();
var db = _services.GetRequiredService<IBotSharpRepository>();
var record = db.GetUserById(curUser.Id);
if (record == null)
var existEmail = db.GetUserByEmail(email);
if (record == null || existEmail != null)
{
return false;
}
db.UpdateUserEmail(record.Id, email);
record.Email = email;
var hooks = _services.GetServices<IAuthenticationHook>();
foreach (var hook in hooks)
{
await hook.UserUpdating(record);
}
db.UpdateUserEmail(record.Id, record.Email);
return true;
}
@ -547,18 +602,23 @@ public class UserService : IUserService
var curUser = await GetMyProfile();
var db = _services.GetRequiredService<IBotSharpRepository>();
var record = db.GetUserById(curUser.Id);
var existPhone = db.GetUserByPhone(phone);
if (record == null)
if (record == null || existPhone != null)
{
return false;
}
if ((record.UserName.Substring(0, 3) == "+86" || record.FirstName.Substring(0, 3) == "+86") && phone.Substring(0, 3) != "+86")
record.Phone = phone;
var hooks = _services.GetServices<IAuthenticationHook>();
foreach (var hook in hooks)
{
phone = $"+86{phone}";
await hook.UserUpdating(record);
}
db.UpdateUserPhone(record.Id, phone);
db.UpdateUserPhone(record.Id, record.Phone);
return true;
}

View file

@ -109,6 +109,13 @@ public class UserController : ControllerBase
return await _userService.VerifyEmailExisting(email);
}
[AllowAnonymous]
[HttpGet("/user/phone/existing")]
public async Task<bool> VerifyPhoneExisting([FromQuery] string phone)
{
return await _userService.VerifyPhoneExisting(phone);
}
[AllowAnonymous]
[HttpPost("/user/verifycode-out")]
public async Task<bool> SendVerificationCodeResetPassword([FromBody] UserCreationModel user)

View file

@ -13,7 +13,7 @@ public partial class MongoRepository
public User? GetUserByPhone(string phone)
{
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Phone == phone);
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Phone == phone && x.Type != UserType.Affiliate);
return user != null ? user.ToUser() : null;
}

View file

@ -67,8 +67,9 @@ public class SummaryPlanFn : IFunctionCallback
var summary = await GetAiResponse(plannerAgent);
message.Content = summary.Content;
await HookEmitter.Emit<IPlanningHook>(_services, x =>
x.OnPlanningCompleted(nameof(TwoStageTaskPlanner), message));
await HookEmitter.Emit<IPlanningHook>(_services, async hook =>
await hook.OnPlanningCompleted(nameof(TwoStageTaskPlanner), message)
);
return true;
}