aboutsummaryrefslogtreecommitdiff
path: root/Backend/Api
diff options
context:
space:
mode:
Diffstat (limited to 'Backend/Api')
-rw-r--r--Backend/Api/Api/Api.csproj1
-rw-r--r--Backend/Api/Api/Controllers/AuthController.cs13
-rw-r--r--Backend/Api/Api/Interfaces/IJwtService.cs2
-rw-r--r--Backend/Api/Api/Interfaces/IUserService.cs6
-rw-r--r--Backend/Api/Api/Program.cs2
-rw-r--r--Backend/Api/Api/Services/JwtService.cs5
-rw-r--r--Backend/Api/Api/Services/UserService.cs62
7 files changed, 82 insertions, 9 deletions
diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj
index dc8b264..10faa3e 100644
--- a/Backend/Api/Api/Api.csproj
+++ b/Backend/Api/Api/Api.csproj
@@ -11,6 +11,7 @@
<PackageReference Include="MongoDB.Driver" Version="2.18.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.24.0" />
+ <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
</ItemGroup>
</Project>
diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs
index 456abd9..6727125 100644
--- a/Backend/Api/Api/Controllers/AuthController.cs
+++ b/Backend/Api/Api/Controllers/AuthController.cs
@@ -33,5 +33,18 @@ namespace Api.Controllers
return Ok();
}
+ [HttpPost("login")]
+ public async Task<ActionResult<string>> Login([FromBody] Login creds)
+ {
+ var id = await _userService.UserIdFromJwt();
+ if (id != null) return Forbid();
+
+ var jwt= await _userService.Login(creds);
+ if (jwt != null)
+ {
+ return Ok(new { token = jwt });
+ }
+ return BadRequest();
+ }
}
}
diff --git a/Backend/Api/Api/Interfaces/IJwtService.cs b/Backend/Api/Api/Interfaces/IJwtService.cs
index 1a8fb0a..f9e5d5f 100644
--- a/Backend/Api/Api/Interfaces/IJwtService.cs
+++ b/Backend/Api/Api/Interfaces/IJwtService.cs
@@ -6,7 +6,7 @@ namespace Api.Interfaces
{
string GenToken(User user);
string TokenToId(string token);
- public string GenEmailToken(User user);
+ public string GenEmailToken(string username);
public string EmailTokenToId(string token);
}
} \ No newline at end of file
diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs
index 8faad45..9e4e3b9 100644
--- a/Backend/Api/Api/Interfaces/IUserService.cs
+++ b/Backend/Api/Api/Interfaces/IUserService.cs
@@ -11,6 +11,12 @@ namespace Api.Interfaces
Task<long> updateUser(User user);
Task<User> deleteUser(String email);
Task<User> getUserById(string id);
+
Task<string> RenewToken(string existingToken);
+ Task<string> Login(Login login);
+ Task<string> Register(Register register);
+ Task<Boolean> VerifyUser(string _id);
+ Task<string> UserIdFromJwt();
+
}
}
diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs
index 26ed445..4643937 100644
--- a/Backend/Api/Api/Program.cs
+++ b/Backend/Api/Api/Program.cs
@@ -23,6 +23,8 @@ builder.Services.AddSingleton<IMongoClient>(s =>
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IJwtService, JwtService>();
+builder.Services.AddHttpContextAccessor();
+
diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs
index 37ec88e..e3688de 100644
--- a/Backend/Api/Api/Services/JwtService.cs
+++ b/Backend/Api/Api/Services/JwtService.cs
@@ -56,13 +56,13 @@ namespace Api.Services
}
}
- public string GenEmailToken(User user)
+ public string GenEmailToken(string username)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value);
var tokenDescriptor = new SecurityTokenDescriptor
{
- Subject = new ClaimsIdentity(new[] { new Claim("username", user.username), new Claim("id", user._id) }),
+ Subject = new ClaimsIdentity(new[] { new Claim("username", username)}),
Expires = DateTime.UtcNow.AddMinutes(30),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
@@ -90,7 +90,6 @@ namespace Api.Services
var jwtToken = (JwtSecurityToken)validatedToken;
var username = (jwtToken.Claims.First(x => x.Type == "username").Value.ToString());
return username;
- //return jwtToken.Claims.First(x => x.Type == "id").Value;
}
catch
{
diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs
index 1260814..7c00c05 100644
--- a/Backend/Api/Api/Services/UserService.cs
+++ b/Backend/Api/Api/Services/UserService.cs
@@ -1,18 +1,22 @@
using Api.Interfaces;
using Api.Models;
using MongoDB.Driver;
+using Microsoft.AspNetCore.Http;
+using System.Security.Claims;
namespace Api.Services
{
public class UserService : IUserService
{
+ private readonly IHttpContextAccessor _httpContext;
private readonly IMongoCollection<User> _users;
private readonly IJwtService _jwtService;
- public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService)
+ public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor)
{
var database = mongoClient.GetDatabase(settings.DatabaseName);
_users = database.GetCollection<User>(settings.UserCollectionName);
_jwtService=jwtService;
+ this._httpContext = httpContextAccessor;
}
public async Task<int> createUser(User user)
@@ -20,8 +24,9 @@ namespace Api.Services
if (await _users.Find(x => x.email == user.email).FirstOrDefaultAsync() != null)
return -1; //email already exists
if (await _users.Find(x => x.username == user.username).FirstOrDefaultAsync() != null)
- return -2; //username already exists
-
+ return -2; //username already
+ //
+ user.password = hashPassword(user.password);
await _users.InsertOneAsync(user);
return 1;
}
@@ -68,6 +73,29 @@ namespace Api.Services
return 0;
}
+ private static int difficulty = 10;
+
+ public static String hashPassword(String password)
+ {
+ String salt = BCrypt.Net.BCrypt.GenerateSalt(difficulty);
+ String passwordHash = BCrypt.Net.BCrypt.HashPassword(password, salt);
+
+ return passwordHash;
+ }
+
+ public static Boolean checkPassword(String plainText, String hash)
+ {
+ Boolean verified = false;
+
+ if (hash == null || !hash.StartsWith("$2a$"))
+ return false;
+
+ verified = BCrypt.Net.BCrypt.Verify(plainText, hash);
+
+ return verified;
+
+ }
+
public async Task<string> Register(Register register)
{
if (await _users.FindAsync(x => x.email == register.email && x.verified==true).Result.AnyAsync())
@@ -87,15 +115,18 @@ namespace Api.Services
}
}
}
+
var user = new User();
user.email = register.email;
user.username = register.username;
user.name = register.name;
user.verified = false;
- user.password = register.password; // unhashed for now
+ user.password = hashPassword(register.password);
+ user.emailToken = _jwtService.GenEmailToken(user.username);
+ await _users.InsertOneAsync(user);
- return "";
+ return "User Registered";
}
public async Task<Boolean> VerifyUser(string _id)
@@ -118,7 +149,28 @@ namespace Api.Services
var user = await getUserById(id);
return _jwtService.GenToken(user);
+ }
+ public async Task<string> Login(Login login)
+ {
+ User user = await _users.FindAsync(x => x.email == login.email).Result.FirstAsync(); // add && x.verified == true after implementing
+ if(user != null && checkPassword(login.password, user.password))
+ {
+ return _jwtService.GenToken(user);
+ }
+ return null;
+ }
+ public async Task<string> UserIdFromJwt()
+ {
+ string id = null;
+ if (_httpContext.HttpContext.User.FindFirstValue("id") != null)
+ {
+ id = _httpContext.HttpContext.User.FindFirstValue("id").ToString();
+ var _id = await _users.FindAsync(x => x._id == id).Result.FirstAsync();
+ if (_id == null)
+ id = null;
+ }
+ return id;
}
}
}