diff --git a/backend/Api/BusinessLogic/DeviceLogic.cs b/backend/Api/BusinessLogic/DeviceLogic.cs
index ebb1d0a..b49db03 100644
--- a/backend/Api/BusinessLogic/DeviceLogic.cs
+++ b/backend/Api/BusinessLogic/DeviceLogic.cs
@@ -3,6 +3,7 @@ using Api.Models;
using Api.Models.Devices;
using Api.Models.Users;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
namespace Api.BusinessLogic
{
@@ -25,14 +26,28 @@ namespace Api.BusinessLogic
/// returns the devices in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
public async Task GetDevices(int userId)
{
- var profile = await _dbAccess.ReadUser(userId);
+ var userDetails = await _dbAccess.ReadUserDetails(userId);
- if (profile == null) { return new ConflictObjectResult(new { message = "Could not find user" }); }
+ if (userDetails.Devices.Count == 0) { return new OkObjectResult(new { message = "Could not find any devices connected to the user" }); }
- var devices = await _dbAccess.ReadDevices(userId);
- if (devices.Count == 0) { return new OkObjectResult(new { message = "Could not find any devices connected to the user" }); }
+ List devices = new List();
+ foreach (var item in userDetails.Devices)
+ {
+ var latestLog = item.Logs?.OrderByDescending(log => log.Date).FirstOrDefault(); // Get the latest log
+ GetDeviceDTO device = new GetDeviceDTO
+ {
+ Id = item.Id,
+ Name = item.Name,
+ TempHigh = item.TempHigh,
+ TempLow = item.TempLow,
+ ReferenceId = item.ReferenceId,
+ LatestLog = latestLog
+ };
+
+ devices.Add(device);
+ }
return new OkObjectResult(devices);
}
@@ -45,12 +60,10 @@ namespace Api.BusinessLogic
/// returns true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
public async Task AddDevice(string referenceId, int userId)
{
- var profile = await _dbAccess.ReadUser(userId);
+ var user = await _dbAccess.ReadUserDetails(userId);
var possibleDevice = _dbAccess.ReadDevice(referenceId);
if (possibleDevice != null) { return new ConflictObjectResult(new { message = "Device with given referenceId already exists" }); }
-
-
- if (profile == null) { return new ConflictObjectResult(new { message = "Could not find user" }); }
+ if (user == null) { return new ConflictObjectResult(new { message = "Could not find user" }); }
Device device = new Device
{
@@ -61,8 +74,49 @@ namespace Api.BusinessLogic
Logs = new List(),
};
+ user.Devices.Add(device);
- return await _dbAccess.CreateDevice(device, userId);
+ return await _dbAccess.CreateDevice(user);
+ }
+
+ ///
+ /// Checks if the deviceId matches a device
+ ///
+ /// The updated info
+ /// The device to be edited
+ /// returns the updated device in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
+ public async Task EditDevice(EditDeviceRequest request, int deviceId)
+ {
+ var device = await _dbAccess.ReadDevice(deviceId);
+ if (device != null)
+ {
+ if (device.Name == "" || device.Name == null)
+ return new ConflictObjectResult(new { message = "Please enter a name" });
+
+ device.Name = request.Name;
+ device.TempLow = request.TempLow;
+ device.TempHigh = request.TempHigh;
+
+ }
+
+ return await _dbAccess.EditDevice(device);
+ }
+
+ ///
+ /// deletes a device
+ ///
+ /// the id used to delete
+ /// Used for deleting device from devices list in user
+ /// returns OK
+ public async Task DeleteDevice(int deviceId)
+ {
+ var device = await _dbAccess.ReadDevice(deviceId);
+ if (device != null)
+ {
+ return await _dbAccess.DeleteDevice(device);
+
+ }
+ return new ConflictObjectResult(new { message = "Invalid user" });
}
///
@@ -83,27 +137,5 @@ namespace Api.BusinessLogic
return new OkObjectResult(logs);
}
-
- ///
- /// Checks if the deviceId matches a device
- ///
- /// The updated info
- /// The device to be edited
- /// returns the updated device in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task EditDevice(EditDeviceRequest device, int deviceId)
- {
- return await _dbAccess.EditDevice(device, deviceId);
- }
-
- ///
- /// deletes a device
- ///
- /// the id used to delete
- /// Used for deleting device from devices list in user
- /// returns OK
- public async Task DeleteDevice(int deviceId, int userId)
- {
- return await _dbAccess.DeleteDevice(deviceId, userId);
- }
}
}
diff --git a/backend/Api/BusinessLogic/UserLogic.cs b/backend/Api/BusinessLogic/UserLogic.cs
index 1a005cf..d17d16a 100644
--- a/backend/Api/BusinessLogic/UserLogic.cs
+++ b/backend/Api/BusinessLogic/UserLogic.cs
@@ -4,12 +4,14 @@ using Api.Models.Devices;
using Api.Models.Users;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
+using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Api.BusinessLogic
{
@@ -26,7 +28,7 @@ namespace Api.BusinessLogic
public async Task getUser(int userId)
{
- User user = await _dbAccess.getUser(userId);
+ User user = await _dbAccess.ReadUser(userId);
if (user == null || user.Id == 0) { return new ConflictObjectResult(new { message = "Could not find user" }); }
return new OkObjectResult(new { user.Id, user.UserName, user.Email });
@@ -40,29 +42,44 @@ namespace Api.BusinessLogic
///
/// The new user
/// returns true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task RegisterUser(User user)
+ public async Task RegisterUser(CreateUserRequest request)
{
- if (!new Regex(@".+@.+\..+").IsMatch(user.Email))
+ if (!new Regex(@".+@.+\..+").IsMatch(request.Email))
{
return new ConflictObjectResult(new { message = "Invalid email address" });
}
- if (!PasswordSecurity(user.Password))
+ if (!PasswordSecurity(request.Password))
{
return new ConflictObjectResult(new { message = "Password is not up to the security standard" });
}
- if (user.Devices == null)
+ var users = await _dbAccess.ReadAllUsers();
+
+ foreach (var item in users)
{
- user.Devices = new List();
+ if (item.UserName == request.UserName)
+ {
+ return new ConflictObjectResult(new { message = "Username is already in use." });
+ }
+
+ if (item.Email == request.Email)
+ {
+ return new ConflictObjectResult(new { message = "Email is being used already" });
+ }
}
string salt = Guid.NewGuid().ToString();
- string hashedPassword = ComputeHash(user.Password, SHA256.Create(), salt);
-
- user.Salt = salt;
- user.Password = hashedPassword;
+ string hashedPassword = ComputeHash(request.Password, SHA256.Create(), salt);
+ User user = new User
+ {
+ UserName = request.UserName,
+ Email = request.Email,
+ Password = hashedPassword,
+ Salt = salt,
+ Devices = new List()
+ };
return await _dbAccess.CreateUser(user);
}
@@ -75,7 +92,7 @@ namespace Api.BusinessLogic
/// Returns a jwt token, username and userid
public async Task Login(Login login)
{
- User user = await _dbAccess.Login(login);
+ User user = await _dbAccess.ReadUserForLogin(login.EmailOrUsrn);
if (user == null || user.Id == 0) { return new ConflictObjectResult(new { message = "Could not find user" }); }
@@ -84,8 +101,8 @@ namespace Api.BusinessLogic
if (user.Password == hashedPassword)
{
var token = GenerateJwtToken(user);
- user.RefreshToken = Guid.NewGuid().ToString();
- _dbAccess.UpdatesRefreshToken(user.RefreshToken, user.Id);
+ user = await UpdateRefreshToken(user);
+
return new OkObjectResult(new { token, user.UserName, user.Id, refreshToken = user.RefreshToken });
}
@@ -103,12 +120,42 @@ namespace Api.BusinessLogic
/// returns the updated user in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
public async Task EditProfile(EditUserRequest userRequest, int userId)
{
- return await _dbAccess.UpdateUser(userRequest, userId);
+ var profile = await _dbAccess.ReadUser(userId);
+ var users = await _dbAccess.ReadAllUsers();
+
+ if (profile == null) { return new ConflictObjectResult(new { message = "User does not exist" }); }
+
+ foreach (var item in users)
+ {
+ if (item.UserName == userRequest.UserName && userId != item.Id)
+ {
+ return new ConflictObjectResult(new { message = "Username is already in use." });
+ }
+
+ if (item.Email == userRequest.Email && userId != item.Id)
+ {
+ return new ConflictObjectResult(new { message = "Email is being used already" });
+ }
+ }
+
+ if (userRequest.Email == "" || userRequest.Email == null)
+ return new ConflictObjectResult(new { message = "Please enter an email" });
+
+ if (userRequest.UserName == "" || userRequest.UserName == null)
+ return new ConflictObjectResult(new { message = "Please enter a username" });
+
+ profile.Email = userRequest.Email;
+ profile.UserName = userRequest.UserName;
+
+
+ return await _dbAccess.UpdateUser(profile);
}
public async Task changePassword(ChangePasswordRequest passwordRequest, int userId)
{
var user = await _dbAccess.ReadUser(userId);
+ if (user == null) { return new ConflictObjectResult(new { message = "User does not exist" }); }
+
string hashedPassword = ComputeHash(passwordRequest.OldPassword, SHA256.Create(), user.Salt);
@@ -124,8 +171,9 @@ namespace Api.BusinessLogic
}
string hashedNewPassword = ComputeHash(passwordRequest.NewPassword, SHA256.Create(), user.Salt);
+ user.Password = hashedNewPassword;
- return await _dbAccess.updatePassword(hashedNewPassword, userId);
+ return await _dbAccess.updatePassword(user);
}
///
@@ -135,12 +183,19 @@ namespace Api.BusinessLogic
/// returns the true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
public async Task DeleteUser(int userId)
{
- return await _dbAccess.DeleteUser(userId);
+ var user = await _dbAccess.ReadUserDetails(userId);
+ if (user != null)
+ {
+ return await _dbAccess.DeleteUser(user);
+
+ }
+ return new ConflictObjectResult(new { message = "Invalid user" });
+
}
public async Task RefreshToken(string refreshToken)
{
- User user = await _dbAccess.ReadUser(refreshToken);
+ User user = await _dbAccess.ReadUserByRefreshToken(refreshToken);
if (user == null) { return new ConflictObjectResult(new { message = "Could not match refreshtoken" }); }
return new OkObjectResult(GenerateJwtToken(user));
}
@@ -206,5 +261,13 @@ namespace Api.BusinessLogic
return new JwtSecurityTokenHandler().WriteToken(token);
}
+
+ private async Task UpdateRefreshToken(User user)
+ {
+ user.RefreshToken = Guid.NewGuid().ToString();
+ user.RefreshTokenExpiresAt = DateTime.Now.AddDays(7);
+ await _dbAccess.UpdateUser(user);
+ return user;
+ }
}
}
diff --git a/backend/Api/Controllers/DeviceController.cs b/backend/Api/Controllers/DeviceController.cs
index ac3693b..ffafd8e 100644
--- a/backend/Api/Controllers/DeviceController.cs
+++ b/backend/Api/Controllers/DeviceController.cs
@@ -75,10 +75,10 @@ namespace Api.Controllers
[HttpDelete("Delete/{deviceId}")]
public async Task DeleteDevice(int deviceId)
{
- var claims = HttpContext.User.Claims;
- string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
- int userId = Convert.ToInt32(userIdString);
- return await _deviceLogic.DeleteDevice(deviceId, userId);
+ //var claims = HttpContext.User.Claims;
+ //string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
+ //int userId = Convert.ToInt32(userIdString);
+ return await _deviceLogic.DeleteDevice(deviceId);
}
}
}
diff --git a/backend/Api/Controllers/UserController.cs b/backend/Api/Controllers/UserController.cs
index de1267f..e5a6a72 100644
--- a/backend/Api/Controllers/UserController.cs
+++ b/backend/Api/Controllers/UserController.cs
@@ -36,7 +36,7 @@ namespace Api.Controllers
// Sends the user to userLogic
[HttpPost("Create")]
- public async Task CreateUser([FromBody] User user)
+ public async Task CreateUser([FromBody] CreateUserRequest user)
{
return await _userLogic.RegisterUser(user);
}
diff --git a/backend/Api/DBAccess/DBAccess.cs b/backend/Api/DBAccess/DBAccess.cs
index ad33dfd..fd887ac 100644
--- a/backend/Api/DBAccess/DBAccess.cs
+++ b/backend/Api/DBAccess/DBAccess.cs
@@ -7,7 +7,7 @@ using Api.Models.Users;
using Microsoft.AspNetCore.Http.HttpResults;
using System.Collections.Generic;
-
+//All EF Core database calls
namespace Api.DBAccess
{
public class DbAccess
@@ -18,82 +18,71 @@ namespace Api.DBAccess
{
_context = context;
}
-
- public async Task getUser(int userId)
- {
- return await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
- }
-
///
- /// Creates a user using entityframework core
+ /// Gets one user on id
///
- /// Need the entire user obj
- /// returns true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task CreateUser(User user)
- {
- var users = await _context.Users.ToListAsync();
-
- foreach (var item in users)
- {
- if (item.UserName == user.UserName)
- {
- return new ConflictObjectResult(new { message = "Username is already in use." });
- }
-
- if (item.Email == user.Email)
- {
- return new ConflictObjectResult(new { message = "Email is being used already" });
- }
- }
-
- _context.Users.Add(user);
- bool saved = await _context.SaveChangesAsync() == 1;
-
- if (saved) { return new OkObjectResult(true); }
-
- return new ConflictObjectResult(new { message = "Could not save to databse" });
- }
-
- ///
- /// Returns a user that matches either the email or username
- ///
- /// Has a username or email and a password here the password is not used
- /// (user) that matches the login
- public async Task Login(Login login)
- {
- User user = new User();
- if (!login.EmailOrUsrn.Contains("@"))
- {
- user = await _context.Users.FirstOrDefaultAsync(u => u.UserName == login.EmailOrUsrn);
- }
- else
- {
- user = await _context.Users.FirstOrDefaultAsync(u => u.Email == login.EmailOrUsrn);
- }
-
- if (user == null || user.Id == 0) { return new User(); }
- return user;
- }
-
- // Returns a user according to userID
+ /// used to get the specific user
+ /// returns a user object from the database based on the given id
public async Task ReadUser(int userId)
{
return await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
}
+ public async Task ReadUserDetails(int userId)
+ {
+ return await _context.Users
+ .Include(u => u.Devices)
+ .ThenInclude(u => u.Logs)
+ .FirstOrDefaultAsync(u => u.Id == userId);
+ }
+
// Returns a user according to refreshToken
- public async Task ReadUser(string refreshToken)
+ public async Task ReadUserByRefreshToken(string refreshToken)
{
return await _context.Users.FirstOrDefaultAsync(u => u.RefreshToken == refreshToken);
}
- // Updates the refreshtoken saved in DB
- public async void UpdatesRefreshToken(string refreshToken, int userId)
+ ///
+ /// Used to check both email and login for the login.
+ ///
+ /// stores the input of username or email
+ /// returns a user object from the database based on the given email or username
+ public async Task ReadUserForLogin(string emailOrUsername)
{
- var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
+ if (emailOrUsername.Contains("@"))
+ {
+ return await _context.Users.FirstOrDefaultAsync(u => u.Email == emailOrUsername);
+ }
+ else
+ {
+ return await _context.Users.FirstOrDefaultAsync(u => u.UserName == emailOrUsername);
+ }
+ }
+
+ ///
+ /// Gets all users
+ ///
+ /// Return a list of users
+ public async Task> ReadAllUsers()
+ {
+ return await _context.Users.ToListAsync();
+ }
+
+ ///
+ /// Creates a user
+ ///
+ /// Need the entire user obj
+ /// returns true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
+ public async Task CreateUser(User user)
+ {
+ _context.Users.Add(user);
+
+ bool saved = await _context.SaveChangesAsync() == 1;
+
+ if (saved) { return new OkObjectResult(true); }
+
+ return new ConflictObjectResult(new { message = "Could not save to database" });
- user.RefreshToken = refreshToken;
- user.RefreshTokenExpiresAt = DateTime.Now.AddDays(7);
}
///
@@ -102,55 +91,25 @@ namespace Api.DBAccess
/// Contains the updated user info
/// Has the id for the user that is to be updated
/// returns the updated user in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task UpdateUser(EditUserRequest user, int userId)
+ public async Task UpdateUser(User user)
{
- var profile = await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
- var users = await _context.Users.ToListAsync();
-
- if (profile == null) { return new ConflictObjectResult(new { message = "User does not exist" }); }
-
- foreach (var item in users)
- {
- if (item.UserName == user.UserName && userId != item.Id)
- {
- return new ConflictObjectResult(new { message = "Username is already in use." });
- }
-
- if (item.Email == user.Email && userId != item.Id)
- {
- return new ConflictObjectResult(new { message = "Email is being used already" });
- }
- }
-
- if(user.Email == "" || user.Email == null)
- return new ConflictObjectResult(new { message = "Please enter an email" });
-
- if (user.UserName == "" || user.UserName == null)
- return new ConflictObjectResult(new { message = "Please enter a username" });
-
- profile.Email = user.Email;
- profile.UserName = user.UserName;
-
-
+ _context.Entry(user).State = EntityState.Modified;
bool saved = await _context.SaveChangesAsync() == 1;
- if (saved) { return new OkObjectResult(profile); }
+ if (saved) { return new OkObjectResult(user);}
return new ConflictObjectResult(new { message = "Could not save to database" });
+
}
- public async Task updatePassword(string newPassword, int userId)
+ public async Task updatePassword(User user)
{
- var profile = await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
-
- if (profile == null) { return new ConflictObjectResult(new { message = "User does not exist" }); }
-
- profile.Password = newPassword;
+ _context.Entry(user).State = EntityState.Modified;
bool saved = await _context.SaveChangesAsync() == 1;
- if (saved) { return new OkObjectResult(profile); }
+ if (saved) { return new OkObjectResult(user); }
return new ConflictObjectResult(new { message = "Could not save to database" });
}
@@ -160,90 +119,50 @@ namespace Api.DBAccess
///
/// The Id of the user that is to be deleted
/// returns true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task DeleteUser(int userId)
+ public async Task DeleteUser(User user)
{
- var user = await _context.Users.Include(u => u.Devices).FirstOrDefaultAsync(u => u.Id == userId);
- if (user != null)
- {
- if (user.Devices != null && user.Devices.Count > 0)
- {
- foreach (var item in user.Devices)
- {
- var device = await _context.Devices.Include(d => d.Logs).FirstOrDefaultAsync(d => d.Id == item.Id);
- if (device != null) { _context.Devices.Remove(device); }
- }
- }
- _context.Users.Remove(user);
- bool saved = await _context.SaveChangesAsync() >= 0;
-
- if (saved) { return new OkObjectResult(saved); }
-
- return new ConflictObjectResult(new { message = "Could not save to database" });
- }
- return new ConflictObjectResult(new { message = "Invalid user" });
- }
-
- // Returns devices according to userID
- public async Task> ReadDevices(int userId)
- {
- var user = await _context.Users.Include(u => u.Devices).ThenInclude(u => u.Logs).FirstOrDefaultAsync(u => u.Id == userId);
-
- if (user == null || user.Devices == null) { return new List(); }
-
- List devices = new List();
-
- foreach (var item in user.Devices)
- {
- var latestLog = item.Logs?.OrderByDescending(log => log.Date).FirstOrDefault(); // Get the latest log
- GetDeviceDTO device = new GetDeviceDTO
- {
- Id = item.Id,
- Name = item.Name,
- TempHigh = item.TempHigh,
- TempLow = item.TempLow,
- ReferenceId = item.ReferenceId,
- LatestLog = latestLog
- };
-
- devices.Add(device);
- }
-
- return devices;
- }
-
- ///
- /// Creates a user using entityframework core
- ///
- /// The device that is going to be created
- /// The user that owns the device
- /// returns the true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task CreateDevice(Device device, int userId)
- {
- var user = await _context.Users.Include(u => u.Devices).FirstOrDefaultAsync(u => u.Id == userId);
-
- if (user == null || user.Devices == null) { return new ConflictObjectResult(new { message = "User did not have a device list" }); }
-
- user.Devices.Add(device);
-
- bool saved = await _context.SaveChangesAsync() == 1;
+ _context.Users.Remove(user);
+ bool saved = await _context.SaveChangesAsync() >= 0;
if (saved) { return new OkObjectResult(saved); }
return new ConflictObjectResult(new { message = "Could not save to database" });
}
+ // Returns all devices
+ public List ReadDevices()
+ {
+ return _context.Devices.ToList();
+ }
+
// Returns a device according to deviceId
public async Task ReadDevice(int deviceId)
{
return await _context.Devices.FirstOrDefaultAsync(d => d.Id == deviceId);
}
- // Returns a device according to refenreId
+ // Returns a device according to referenceId
public Device ReadDevice(string referenceId)
{
return _context.Devices.FirstOrDefault(d => d.ReferenceId == referenceId);
}
+ ///
+ /// Creates a user using entityframework core
+ ///
+ /// The device that is going to be created
+ /// The user that owns the device
+ /// returns the true in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
+ public async Task CreateDevice(User user)
+ {
+ _context.Entry(user).State = EntityState.Modified;
+
+ bool saved = await _context.SaveChangesAsync() == 2;
+
+ if (saved) { return new OkObjectResult(user.Id); }
+
+ return new ConflictObjectResult(new { message = "Could not save to database" });
+ }
///
/// Updates a device in the database
@@ -251,62 +170,25 @@ namespace Api.DBAccess
/// Contains the updated device info
/// Has the id for the device that is to be updated
/// returns the updated device in a OkObjectResult and if there is some error it returns a ConflictObjectResult and a message that explain the reason
- public async Task EditDevice(EditDeviceRequest request, int deviceId)
+ public async Task EditDevice(Device device)
{
- var device = await _context.Devices.FirstOrDefaultAsync(d => d.Id == deviceId);
- if (device != null)
- {
- if (device.Name == "" || device.Name == null)
- return new ConflictObjectResult(new { message = "Please enter a name" });
+ _context.Entry(device).State = EntityState.Modified;
+
+ bool saved = await _context.SaveChangesAsync() == 1;
- device.Name = request.Name;
- device.TempLow = request.TempLow;
- device.TempHigh = request.TempHigh;
+ if (saved) { return new OkObjectResult(device); }
- bool saved = await _context.SaveChangesAsync() >= 0;
-
- if (saved) { return new OkObjectResult(saved); }
-
- return new ConflictObjectResult(new { message = "Could not save to database" });
- }
- return new ConflictObjectResult(new { message = "Invalid device. May already be deleted" });
+ return new ConflictObjectResult(new { message = "Could not save to database" });
}
- public async Task DeleteDevice(int deviceId, int userId)
+ public async Task DeleteDevice(Device device)
{
- var user = await _context.Users
- .Include(u => u.Devices) // Ensure devices are loaded
- .FirstOrDefaultAsync(u => u.Id == userId);
+ _context.Devices.Remove(device);
+ bool saved = await _context.SaveChangesAsync() >= 0;
- if (user == null)
- {
- return new NotFoundObjectResult(new { message = "User not found" });
- }
+ if (saved) { return new OkObjectResult(saved); }
- var device = user.Devices?.FirstOrDefault(d => d.Id == deviceId);
-
- if (device != null || user.Devices != null)
- {
- user.Devices.Remove(device);
- bool userDeviceDeleted = await _context.SaveChangesAsync() > 0;
- if (userDeviceDeleted)
- {
- _context.Devices.Remove(device);
- bool saved = await _context.SaveChangesAsync() > 0;
-
- if (saved) return new OkObjectResult(new { message = "Device deleted successfully" });
- }
-
- return new ConflictObjectResult(new { message = "Could not save to database" });
- }
-
- return new NotFoundObjectResult(new { message = "Device not found or already deleted" });
- }
-
- // Returns all devices
- public List ReadDevices()
- {
- return _context.Devices.ToList();
+ return new ConflictObjectResult(new { message = "Could not save to database" });
}
///
diff --git a/backend/Api/Migrations/20250403144251_removeNullableLists.Designer.cs b/backend/Api/Migrations/20250403144251_removeNullableLists.Designer.cs
new file mode 100644
index 0000000..04ae996
--- /dev/null
+++ b/backend/Api/Migrations/20250403144251_removeNullableLists.Designer.cs
@@ -0,0 +1,138 @@
+//
+using System;
+using Api;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Api.Migrations
+{
+ [DbContext(typeof(DBContext))]
+ [Migration("20250403144251_removeNullableLists")]
+ partial class removeNullableLists
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "9.0.3");
+
+ modelBuilder.Entity("Api.Models.Devices.Device", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ReferenceId")
+ .HasColumnType("TEXT");
+
+ b.Property("TempHigh")
+ .HasColumnType("REAL");
+
+ b.Property("TempLow")
+ .HasColumnType("REAL");
+
+ b.Property("UserId")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Devices");
+ });
+
+ modelBuilder.Entity("Api.Models.TemperatureLogs", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Date")
+ .HasColumnType("TEXT");
+
+ b.Property("DeviceId")
+ .HasColumnType("INTEGER");
+
+ b.Property("TempHigh")
+ .HasColumnType("REAL");
+
+ b.Property("TempLow")
+ .HasColumnType("REAL");
+
+ b.Property("Temperature")
+ .HasColumnType("REAL");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId");
+
+ b.ToTable("TemperatureLogs");
+ });
+
+ modelBuilder.Entity("Api.Models.Users.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Password")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RefreshToken")
+ .HasColumnType("TEXT");
+
+ b.Property("RefreshTokenExpiresAt")
+ .HasColumnType("TEXT");
+
+ b.Property("Salt")
+ .HasColumnType("TEXT");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Api.Models.Devices.Device", b =>
+ {
+ b.HasOne("Api.Models.Users.User", null)
+ .WithMany("Devices")
+ .HasForeignKey("UserId");
+ });
+
+ modelBuilder.Entity("Api.Models.TemperatureLogs", b =>
+ {
+ b.HasOne("Api.Models.Devices.Device", null)
+ .WithMany("Logs")
+ .HasForeignKey("DeviceId");
+ });
+
+ modelBuilder.Entity("Api.Models.Devices.Device", b =>
+ {
+ b.Navigation("Logs");
+ });
+
+ modelBuilder.Entity("Api.Models.Users.User", b =>
+ {
+ b.Navigation("Devices");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/backend/Api/Migrations/20250403144251_removeNullableLists.cs b/backend/Api/Migrations/20250403144251_removeNullableLists.cs
new file mode 100644
index 0000000..c7aa064
--- /dev/null
+++ b/backend/Api/Migrations/20250403144251_removeNullableLists.cs
@@ -0,0 +1,22 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Api.Migrations
+{
+ ///
+ public partial class removeNullableLists : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+
+ }
+ }
+}
diff --git a/backend/Api/Models/Devices/Device.cs b/backend/Api/Models/Devices/Device.cs
index ee95a16..c41db5f 100644
--- a/backend/Api/Models/Devices/Device.cs
+++ b/backend/Api/Models/Devices/Device.cs
@@ -12,6 +12,6 @@
public string? ReferenceId { get; set; }
- public List? Logs { get; set; }
+ public List Logs { get; set; }
}
}
diff --git a/backend/Api/Models/Users/CreateUserRequest.cs b/backend/Api/Models/Users/CreateUserRequest.cs
new file mode 100644
index 0000000..def72d7
--- /dev/null
+++ b/backend/Api/Models/Users/CreateUserRequest.cs
@@ -0,0 +1,11 @@
+namespace Api.Models.Users
+{
+ public class CreateUserRequest
+ {
+ public string UserName { get; set; }
+
+ public string Password { get; set; }
+
+ public string Email { get; set; }
+ }
+}
diff --git a/backend/Api/Models/Users/User.cs b/backend/Api/Models/Users/User.cs
index e9729fa..05c6a75 100644
--- a/backend/Api/Models/Users/User.cs
+++ b/backend/Api/Models/Users/User.cs
@@ -18,6 +18,6 @@ namespace Api.Models.Users
public DateTime RefreshTokenExpiresAt { get; set; }
- public List? Devices { get; set; }
+ public List Devices { get; set; }
}
}
diff --git a/frontend/profile/index.html b/frontend/profile/index.html
index 98ff11b..9c740e4 100644
--- a/frontend/profile/index.html
+++ b/frontend/profile/index.html
@@ -38,10 +38,10 @@