Fix multiple reset password emails Bug
This commit is contained in:
parent
6e7d337d92
commit
76099131c2
|
@ -7,6 +7,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AWSSDK.S3" Version="3.7.205.17" />
|
||||||
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
||||||
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="6.5.1" />
|
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="6.5.1" />
|
||||||
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" />
|
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" />
|
||||||
|
@ -34,213 +35,20 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../Lib/Utils/Utils.csproj" />
|
<ProjectReference Include="../../Lib/Utils/Utils.csproj" />
|
||||||
<ProjectReference Include="../../Lib/Mailer/Mailer.csproj" />
|
<ProjectReference Include="../../Lib/Mailer/Mailer.csproj" />
|
||||||
<ProjectReference Include="..\..\Lib\S3Utils\S3Utils.csproj" />
|
<ProjectReference Include="../../Lib/S3Utils/S3Utils.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="Resources/s3cmd.py">
|
<None Update="Resources/s3cmd.py">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Remove="DbBackups\db-1692621279.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620662.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620973.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620165.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620475.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692619622.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620266.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692618414.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692618326.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692612258.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692619963.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692620296.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692618125.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692621869.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692621699.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692611631.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692627958.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692715302.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692715647.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692715652.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692884061.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692884224.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692884244.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692884524.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692884642.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692885117.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692885781.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692885908.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692889590.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692889640.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692890673.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692890981.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692891081.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692891207.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692891239.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692891540.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692891640.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692947517.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692951226.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692956795.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692957809.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692958545.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965093.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965087.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965105.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965660.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965676.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693813301.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693815606.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693813151.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693388471.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693385306.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693236515.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693230148.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693301572.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693388748.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693388189.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693297768.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693299939.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693229044.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693225598.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693300771.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693212155.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693225325.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693212119.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693211833.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693392099.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693392147.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693391476.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693395914.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693394644.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389535.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389069.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693812839.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389121.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390948.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693401522.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693299943.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693230582.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693388417.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693238297.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693228621.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693388588.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693823647.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390865.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693395143.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693823298.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389080.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390583.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693391825.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693391007.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390368.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693391131.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693392465.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693820540.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389837.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693394858.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693395207.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693815792.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389713.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693391988.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389959.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693395856.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693488424.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693474277.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693482868.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693472646.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693470245.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693470249.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693469782.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693497578.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693474069.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693499184.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693395013.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693398191.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693394891.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390733.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693389451.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693390182.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693811965.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966481.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692969227.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966381.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692967853.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693820304.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692967068.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693822619.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692969899.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693820664.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966501.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693820595.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966495.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692967782.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693820327.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966486.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692965827.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693581684.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966088.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693207198.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693214346.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692979283.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692979039.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692979326.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693210467.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692970330.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692979087.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692971615.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692970282.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692966463.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692971631.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692967061.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692968130.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692969863.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693574723.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1692969234.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693574756.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693572655.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693572839.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693563487.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571800.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693554456.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571859.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571699.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571694.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693555209.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571639.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693465491.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693571738.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693465474.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693498493.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693575085.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693574598.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693575136.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693574755.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693574962.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693822770.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693822650.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693822757.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693822641.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693823785.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693823723.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693836773.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693837575.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693837906.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693838013.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693837691.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693837666.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693838039.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693838563.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693838248.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693838578.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693839416.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1693839492.sqlite" />
|
|
||||||
<None Remove="DbBackups\db-1694156276.sqlite" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Update="Resources\urlAndKey.json">
|
<Content Update="Resources/urlAndKey.json">
|
||||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.App.Backend.DataTypes.Methods;
|
using InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
@ -21,17 +19,12 @@ public class Controller : ControllerBase
|
||||||
var user = Db.GetUserByEmail(username);
|
var user = Db.GetUserByEmail(username);
|
||||||
|
|
||||||
if (user is null)
|
if (user is null)
|
||||||
{
|
throw new Exceptions(400, "Null User Exception", "Must provide a user to log in as.", Request.Path.Value!);
|
||||||
throw new Exceptions(400,"Null User Exception", "Must provide a user to log in as.", Request.Path.Value!);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(user.Password.IsNullOrEmpty() && user.MustResetPassword))
|
if (!(user.Password.IsNullOrEmpty() && user.MustResetPassword) && !user.VerifyPassword(password))
|
||||||
{
|
|
||||||
if (!user.VerifyPassword(password))
|
|
||||||
{
|
{
|
||||||
//return Unauthorized("No Password set");
|
//return Unauthorized("No Password set");
|
||||||
throw new Exceptions(401,"Wrong Password Exception", "Please try again.", Request.Path.Value!);
|
throw new Exceptions(401, "Wrong Password Exception", "Please try again.", Request.Path.Value!);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
|
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
|
||||||
|
@ -67,7 +60,9 @@ public class Controller : ControllerBase
|
||||||
if (user is null || !session.HasAccessTo(user))
|
if (user is null || !session.HasAccessTo(user))
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
return user.HidePassword().HideParentIfUserHasNoAccessToParent(session);
|
return user
|
||||||
|
.HidePassword()
|
||||||
|
.HideParentIfUserHasNoAccessToParent(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,11 +250,11 @@ public class Controller : ControllerBase
|
||||||
|
|
||||||
|
|
||||||
[HttpPost(nameof(CreateUser))]
|
[HttpPost(nameof(CreateUser))]
|
||||||
public ActionResult<User> CreateUser([FromBody] User newUser, Token authToken)
|
public async Task<ActionResult<User>> CreateUser([FromBody] User newUser, Token authToken)
|
||||||
{
|
{
|
||||||
var create = Db.GetSession(authToken).Create(newUser);
|
var create = Db.GetSession(authToken).Create(newUser);
|
||||||
|
|
||||||
return create && Db.SendNewUserEmail(newUser)
|
return create && await Db.SendNewUserEmail(newUser)
|
||||||
? newUser.HidePassword()
|
? newUser.HidePassword()
|
||||||
: Unauthorized() ;
|
: Unauthorized() ;
|
||||||
}
|
}
|
||||||
|
@ -461,16 +456,17 @@ public class Controller : ControllerBase
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost(nameof(ResetPasswordRequest))]
|
[HttpPost(nameof(ResetPasswordRequest))]
|
||||||
public ActionResult<IEnumerable<Object>> ResetPasswordRequest(String username)
|
public async Task<ActionResult<IEnumerable<Object>>> ResetPasswordRequest(String email)
|
||||||
{
|
{
|
||||||
var user = Db.GetUserByEmail(username);
|
var user = Db.GetUserByEmail(email);
|
||||||
|
|
||||||
if (user is null)
|
if (user is null)
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
|
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
|
||||||
var res = Db.Create(session);
|
var success = Db.Create(session);
|
||||||
return res && Db.SendPasswordResetEmail(user, session.Token)
|
|
||||||
|
return success && await Db.SendPasswordResetEmail(user, session.Token)
|
||||||
? Ok()
|
? Ok()
|
||||||
: Unauthorized();
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Net.Mail;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
|
using InnovEnergy.Lib.Mailer;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using Convert = System.Convert;
|
using Convert = System.Convert;
|
||||||
using static System.Text.Encoding;
|
using static System.Text.Encoding;
|
||||||
|
@ -91,13 +91,14 @@ public static class UserMethods
|
||||||
.Skip(1); // skip self
|
.Skip(1); // skip self
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean VerifyPassword(this User user, String password)
|
public static Boolean VerifyPassword(this User user, String? password)
|
||||||
{
|
{
|
||||||
return Db.GetUserByEmail(user.Email)?.Password == user.SaltAndHashPassword(password);
|
return password is not null
|
||||||
|
&& Db.GetUserByEmail(user.Email)?.Password == user.SaltAndHashPassword(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String? SaltAndHashPassword(this User user, String password)
|
public static String SaltAndHashPassword(this User user, String password)
|
||||||
{
|
{
|
||||||
var dataToHash = $"{password}{user.Salt()}";
|
var dataToHash = $"{password}{user.Salt()}";
|
||||||
|
|
||||||
|
@ -150,8 +151,10 @@ public static class UserMethods
|
||||||
if (installation is null)
|
if (installation is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return user.HasDirectAccessTo(installation) ||
|
return user.HasDirectAccessTo(installation)
|
||||||
installation.Ancestors().Any(user.HasDirectAccessTo);
|
|| installation
|
||||||
|
.Ancestors()
|
||||||
|
.Any(user.HasDirectAccessTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean HasAccessTo(this User user, User? other)
|
public static Boolean HasAccessTo(this User user, User? other)
|
||||||
|
@ -159,10 +162,8 @@ public static class UserMethods
|
||||||
if (other is null)
|
if (other is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (other.Id == user.Id)
|
return other.Id == user.Id
|
||||||
return true;
|
|| other
|
||||||
|
|
||||||
return other
|
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.Contains(user);
|
.Contains(user);
|
||||||
}
|
}
|
||||||
|
@ -189,8 +190,6 @@ public static class UserMethods
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static String Salt(this User user)
|
private static String Salt(this User user)
|
||||||
{
|
{
|
||||||
// + id => salt unique per user
|
// + id => salt unique per user
|
||||||
|
@ -211,4 +210,34 @@ public static class UserMethods
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task SendEmail(this User user, String subject, String body)
|
||||||
|
{
|
||||||
|
return Mailer.Send(user.Name, user.Email, subject, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task SendPasswordResetEmail(this User user, String token)
|
||||||
|
{
|
||||||
|
const String subject = "Reset the password of your InnovEnergy-Account";
|
||||||
|
const String resetLink = "https://monitor.innov.energy/api/ResetPassword"; // TODO: move to settings file
|
||||||
|
|
||||||
|
var body = $"Dear {user.Name}\n" +
|
||||||
|
$"To reset your password " +
|
||||||
|
$"please open this link:{resetLink}?token={token}";
|
||||||
|
|
||||||
|
return user.SendEmail(subject, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task SendNewUserWelcomeMessage(this User user)
|
||||||
|
{
|
||||||
|
const String subject = "Your new InnovEnergy-Account";
|
||||||
|
|
||||||
|
var resetLink = $"https://monitor.innov.energy/?username={user.Email}"; // TODO: move to settings file
|
||||||
|
|
||||||
|
var body = $"Dear {user.Name}\n" +
|
||||||
|
$"To set your password and log in to your " +
|
||||||
|
$"Innovenergy-Account open this link:{resetLink}";
|
||||||
|
|
||||||
|
return user.SendEmail(subject, body);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
using System.Reactive.Concurrency;
|
using System.Reactive.Concurrency;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using CliWrap;
|
|
||||||
using CliWrap.Buffered;
|
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.App.Backend.DataTypes.Methods;
|
using InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
using InnovEnergy.Lib.S3Utils;
|
using InnovEnergy.Lib.S3Utils;
|
||||||
using InnovEnergy.Lib.S3Utils.DataTypes;
|
using InnovEnergy.Lib.S3Utils.DataTypes;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
using SQLiteConnection = SQLite.SQLiteConnection;
|
using SQLiteConnection = SQLite.SQLiteConnection;
|
||||||
|
|
||||||
|
@ -39,34 +38,14 @@ public static partial class Db
|
||||||
memoryConnection.CreateTable<Session>();
|
memoryConnection.CreateTable<Session>();
|
||||||
memoryConnection.CreateTable<OrderNumber2Installation>();
|
memoryConnection.CreateTable<OrderNumber2Installation>();
|
||||||
|
|
||||||
foreach (var obj in fileConnection.Table<Session>())
|
fileConnection.Table<Session> ().ForEach(memoryConnection.Insert);
|
||||||
{
|
fileConnection.Table<Folder> ().ForEach(memoryConnection.Insert);
|
||||||
memoryConnection.Insert(obj);
|
fileConnection.Table<Installation> ().ForEach(memoryConnection.Insert);
|
||||||
}
|
fileConnection.Table<User> ().ForEach(memoryConnection.Insert);
|
||||||
foreach (var obj in fileConnection.Table<Folder>())
|
fileConnection.Table<FolderAccess> ().ForEach(memoryConnection.Insert);
|
||||||
{
|
fileConnection.Table<InstallationAccess> ().ForEach(memoryConnection.Insert);
|
||||||
memoryConnection.Insert(obj);
|
fileConnection.Table<OrderNumber2Installation>().ForEach(memoryConnection.Insert);
|
||||||
}
|
|
||||||
foreach (var obj in fileConnection.Table<Installation>())
|
|
||||||
{
|
|
||||||
memoryConnection.Insert(obj);
|
|
||||||
}
|
|
||||||
foreach (var obj in fileConnection.Table<User>())
|
|
||||||
{
|
|
||||||
memoryConnection.Insert(obj);
|
|
||||||
}
|
|
||||||
foreach (var obj in fileConnection.Table<FolderAccess>())
|
|
||||||
{
|
|
||||||
memoryConnection.Insert(obj);
|
|
||||||
}
|
|
||||||
foreach (var obj in fileConnection.Table<InstallationAccess>())
|
|
||||||
{
|
|
||||||
memoryConnection.Insert(obj);
|
|
||||||
}
|
|
||||||
foreach (var obj in fileConnection.Table<OrderNumber2Installation>())
|
|
||||||
{
|
|
||||||
memoryConnection.Insert(obj);
|
|
||||||
}
|
|
||||||
return memoryConnection;
|
return memoryConnection;
|
||||||
}))();
|
}))();
|
||||||
|
|
||||||
|
@ -153,33 +132,52 @@ public static partial class Db
|
||||||
{
|
{
|
||||||
var regions = Installations
|
var regions = Installations
|
||||||
.Select(i => i.S3Region)
|
.Select(i => i.S3Region)
|
||||||
.Distinct().ToList();
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
const String provider = "exo.io";
|
const String provider = "exo.io";
|
||||||
|
|
||||||
foreach (var region in regions)
|
foreach (var region in regions)
|
||||||
{
|
{
|
||||||
var bucketList = await new S3Region($"https://{region}.{provider}", ExoCmd.S3Creds!).ListAllBuckets();
|
var s3Region = new S3Region($"https://{region}.{provider}", ExoCmd.S3Creds!);
|
||||||
|
var bucketList = await s3Region.ListAllBuckets();
|
||||||
|
|
||||||
foreach (var bucket in bucketList.Buckets)
|
var installations = from bucket in bucketList.Buckets
|
||||||
{
|
from installation in Installations
|
||||||
foreach (var installation in Installations)
|
where installation.BucketName() == bucket.BucketName
|
||||||
{
|
select installation;
|
||||||
if (installation.BucketName() == bucket.BucketName)
|
|
||||||
|
foreach (var installation in installations)
|
||||||
{
|
{
|
||||||
await installation.RenewS3Credentials();
|
await installation.RenewS3Credentials();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<Boolean> SendPasswordResetEmail(User user, String sessionToken)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await user.SendPasswordResetEmail(sessionToken);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean SendPasswordResetEmail(User user, String sessionToken)
|
public static async Task<Boolean> SendNewUserEmail(User user)
|
||||||
{
|
{
|
||||||
return Email.Email.SendPasswordResetMessage(user, sessionToken);
|
try
|
||||||
|
{
|
||||||
|
await user.SendNewUserWelcomeMessage();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
public static Boolean SendNewUserEmail(User user)
|
|
||||||
{
|
{
|
||||||
return Email.Email.SendNewUserMessage(user);
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean DeleteUserPassword(User user)
|
public static Boolean DeleteUserPassword(User user)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.App.Backend.DataTypes.Methods;
|
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,10 +25,10 @@ public static partial class Db
|
||||||
.FirstOrDefault(u => u.Id == id);
|
.FirstOrDefault(u => u.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User? GetUserByEmail(String userName)
|
public static User? GetUserByEmail(String email)
|
||||||
{
|
{
|
||||||
return Users
|
return Users
|
||||||
.FirstOrDefault(u => u.Email == userName);
|
.FirstOrDefault(u => u.Email == email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Session? GetSession(String token)
|
public static Session? GetSession(String token)
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
|
||||||
using InnovEnergy.Lib.Mailer;
|
|
||||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Email;
|
|
||||||
public static class Email
|
|
||||||
{
|
|
||||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
|
||||||
public static Boolean SendVerificationMessage(User emailRecipientUser)
|
|
||||||
{
|
|
||||||
var config = JsonSerializer.Deserialize<SmtpConfig>(File.OpenRead("./Resources/smtpConfig.json"))!;
|
|
||||||
var mailer = new Mailer();
|
|
||||||
|
|
||||||
mailer.From("InnovEnergy", "noreply@innov.energy");
|
|
||||||
mailer.To(emailRecipientUser.Name, emailRecipientUser.Email);
|
|
||||||
|
|
||||||
mailer.Subject("Create a new password for your Innovenergy-Account");
|
|
||||||
mailer.Body("Dear " + emailRecipientUser.Name +
|
|
||||||
"\n Please create a new password for your Innovenergy-account." +
|
|
||||||
"\n To do this just login at https://HEEEEELP");
|
|
||||||
|
|
||||||
return mailer.SendEmailUsingSmtpConfig(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
|
||||||
public static Boolean SendPasswordResetMessage (User emailRecipientUser, String token)
|
|
||||||
{
|
|
||||||
var config = JsonSerializer.Deserialize<SmtpConfig>(File.OpenRead("./Resources/smtpConfig.json"))!;
|
|
||||||
|
|
||||||
//todo am I right?
|
|
||||||
const String resetLink = "https://monitor.innov.energy/api/ResetPassword";
|
|
||||||
var mailer = new Mailer();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
mailer.From("InnovEnergy", "noreply@innov.energy");
|
|
||||||
mailer.To(emailRecipientUser.Name, emailRecipientUser.Email);
|
|
||||||
|
|
||||||
mailer.Subject("Reset the password of your Innovenergy-Account");
|
|
||||||
mailer.Body("Dear " + emailRecipientUser.Name
|
|
||||||
+ "\n To reset your password open this link:"
|
|
||||||
+ resetLink + "?token="
|
|
||||||
+ token);
|
|
||||||
|
|
||||||
return mailer.SendEmailUsingSmtpConfig(config);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
|
||||||
public static Boolean SendNewUserMessage (User emailRecipientUser)
|
|
||||||
{
|
|
||||||
var config = JsonSerializer.Deserialize<SmtpConfig>(File.OpenRead("./Resources/smtpConfig.json"))!;
|
|
||||||
|
|
||||||
//todo am I right?
|
|
||||||
var resetLink = $"https://monitor.innov.energy/?username={emailRecipientUser.Email}";
|
|
||||||
var mailer = new Mailer();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
mailer.From("InnovEnergy", "noreply@innov.energy");
|
|
||||||
mailer.To(emailRecipientUser.Name, emailRecipientUser.Email);
|
|
||||||
|
|
||||||
mailer.Subject("Your new Innovenergy-Account");
|
|
||||||
mailer.Body("Dear " + emailRecipientUser.Name
|
|
||||||
+ "\n To set your password and log in to your Innovenergy-Account open this link:"
|
|
||||||
+ resetLink);
|
|
||||||
|
|
||||||
return mailer.SendEmailUsingSmtpConfig(config);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ using InnovEnergy.App.Backend.Database;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using System.Net;
|
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend;
|
namespace InnovEnergy.App.Backend;
|
||||||
|
@ -20,7 +19,7 @@ public static class Program
|
||||||
builder.Services.AddProblemDetails(setup =>
|
builder.Services.AddProblemDetails(setup =>
|
||||||
{
|
{
|
||||||
//This includes the stacktrace in Development Env
|
//This includes the stacktrace in Development Env
|
||||||
setup.IncludeExceptionDetails = (ctx, env) => builder.Environment.IsDevelopment() || builder.Environment.IsStaging();
|
setup.IncludeExceptionDetails = (_, _) => builder.Environment.IsDevelopment() || builder.Environment.IsStaging();
|
||||||
|
|
||||||
//This handles our Exceptions
|
//This handles our Exceptions
|
||||||
setup.Map<Exceptions>(exception => new ProblemDetails
|
setup.Map<Exceptions>(exception => new ProblemDetails
|
||||||
|
@ -43,8 +42,6 @@ public static class Program
|
||||||
|
|
||||||
app.Use(async (context, next) =>
|
app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
var x = 2;
|
|
||||||
|
|
||||||
context.Request.WriteLine();
|
context.Request.WriteLine();
|
||||||
|
|
||||||
await next(context);
|
await next(context);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AWSSDK.S3" Version="3.7.203.12" />
|
<PackageReference Include="AWSSDK.S3" Version="3.7.205.17" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,55 +1,41 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Mailer;
|
namespace InnovEnergy.Lib.Mailer;
|
||||||
|
|
||||||
|
|
||||||
public class Mailer
|
public static class Mailer
|
||||||
{
|
{
|
||||||
private static MimeMessage Email = new();
|
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||||
|
public static async Task Send(String recipientName, String recipientEmailAddress, String subject, String body)
|
||||||
|
{
|
||||||
|
var config = await ReadMailerConfig();
|
||||||
|
|
||||||
public MimeMessage To(String name, String emailAddress)
|
var from = new MailboxAddress(config!.SenderName, config.SenderAddress);
|
||||||
{
|
var to = new MailboxAddress(recipientName, recipientEmailAddress);
|
||||||
Email.To.Add(new MailboxAddress(name, emailAddress));
|
|
||||||
return Email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MimeMessage From(String name, String emailAddress)
|
var msg = new MimeMessage
|
||||||
{
|
{
|
||||||
Email.From.Add(new MailboxAddress(name, emailAddress));
|
From = { from },
|
||||||
return Email;
|
To = { to },
|
||||||
}
|
Subject = subject,
|
||||||
|
Body = new TextPart { Text = body }
|
||||||
public MimeMessage Subject(String subjectText)
|
|
||||||
{
|
|
||||||
Email.Subject = subjectText;
|
|
||||||
return Email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MimeMessage Body(String bodyText)
|
|
||||||
{
|
|
||||||
Email.Body = new TextPart(MimeKit.Text.TextFormat.Plain)
|
|
||||||
{
|
|
||||||
Text = bodyText
|
|
||||||
};
|
};
|
||||||
return Email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean SendEmailUsingSmtpConfig(SmtpConfig config)
|
|
||||||
{
|
|
||||||
try{
|
|
||||||
using var smtp = new SmtpClient();
|
using var smtp = new SmtpClient();
|
||||||
smtp.Connect(config.Url, config.Port, false);
|
|
||||||
|
|
||||||
smtp.Authenticate(config.Username, config.Password);
|
await smtp.ConnectAsync(config.SmtpServerUrl, config.SmtpPort, false);
|
||||||
|
await smtp.AuthenticateAsync(config.SmtpUsername, config.SmtpPassword);
|
||||||
smtp.Send(Email);
|
await smtp.SendAsync(msg);
|
||||||
smtp.Disconnect(true);
|
await smtp.DisconnectAsync(true);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
|
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.DeserializeAsync<TValue>(Stream, JsonSerializerOptions, CancellationToken)")]
|
||||||
|
private static async Task<MailerConfig?> ReadMailerConfig()
|
||||||
{
|
{
|
||||||
return false;
|
await using var fileStream = File.OpenRead(MailerConfig.DefaultFile);
|
||||||
}
|
return await JsonSerializer.DeserializeAsync<MailerConfig>(fileStream);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,4 +7,16 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MailKit" Version="4.2.0" />
|
<PackageReference Include="MailKit" Version="4.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="MailerConfig.json">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="../Utils/Utils.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
namespace InnovEnergy.Lib.Mailer;
|
||||||
|
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
|
public class MailerConfig
|
||||||
|
{
|
||||||
|
public required String SmtpServerUrl { get; init; }
|
||||||
|
public required String SmtpUsername { get; init; }
|
||||||
|
public required String SmtpPassword { get; init; }
|
||||||
|
public UInt16 SmtpPort { get; init; } = 587;
|
||||||
|
|
||||||
|
public required String SenderName { get; init; }
|
||||||
|
public required String SenderAddress { get; init; }
|
||||||
|
|
||||||
|
public const String DefaultFile = $"{nameof(MailerConfig)}.json";
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"SmtpServerUrl" : "mail.agenturserver.de",
|
||||||
|
"SmtpUsername" : "p518526p69",
|
||||||
|
"SmtpPassword" : "i;b*xqm4iB5uhl",
|
||||||
|
"SmtpPort" : 587,
|
||||||
|
"SenderName" : "InnovEnergy",
|
||||||
|
"SenderAddress" : "noreply@innov.energy"
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
namespace InnovEnergy.Lib.Mailer;
|
|
||||||
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
|
||||||
public class SmtpConfig
|
|
||||||
{
|
|
||||||
public String Url { get; init; } = null!;
|
|
||||||
public String Username { get; init; } = null!;
|
|
||||||
public String Password { get; init; } = null!;
|
|
||||||
public Int32 Port { get; init; } = 587;
|
|
||||||
}
|
|
|
@ -42,9 +42,9 @@ public static class S3
|
||||||
.Select(o => new S3Url(o.Key, bucket));
|
.Select(o => new S3Url(o.Key, bucket));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ListBucketsResponse> ListAllBuckets(this S3Region region)
|
public static Task<ListBucketsResponse> ListAllBuckets(this S3Region region)
|
||||||
{
|
{
|
||||||
return await region
|
return region
|
||||||
.GetS3Client()
|
.GetS3Client()
|
||||||
.ListBucketsAsync();
|
.ListBucketsAsync();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue