Skip to content

Commit

Permalink
Merge branch 'develop' into feature/hub-more-info
Browse files Browse the repository at this point in the history
  • Loading branch information
LucHeart committed Nov 6, 2024
2 parents 603d741 + c8406a4 commit e5fa232
Show file tree
Hide file tree
Showing 44 changed files with 1,940 additions and 150 deletions.
3 changes: 2 additions & 1 deletion API/Controller/Account/Login.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Asp.Versioning;
using OpenShock.API.Services.Account;
using OpenShock.Common;
using OpenShock.Common.Constants;
using OpenShock.Common.Errors;
using OpenShock.Common.Problems;
using OpenShock.Common.Utils;
Expand Down Expand Up @@ -41,7 +42,7 @@ public async Task<IActionResult> Login(

HttpContext.Response.Cookies.Append("openShockSession", loginAction.AsT0.Value, new CookieOptions
{
Expires = new DateTimeOffset(DateTime.UtcNow.Add(Constants.LoginSessionLifetime)),
Expires = new DateTimeOffset(DateTime.UtcNow.Add(Duration.LoginSessionLifetime)),
Secure = true,
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Expand Down
3 changes: 2 additions & 1 deletion API/Controller/Account/LoginV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Asp.Versioning;
using OpenShock.API.Services.Account;
using OpenShock.Common;
using OpenShock.Common.Constants;
using OpenShock.Common.Errors;
using OpenShock.Common.Problems;
using OpenShock.Common.Services.Turnstile;
Expand Down Expand Up @@ -48,7 +49,7 @@ public async Task<IActionResult> LoginV2(

HttpContext.Response.Cookies.Append("openShockSession", loginAction.AsT0.Value, new CookieOptions
{
Expires = new DateTimeOffset(DateTime.UtcNow.Add(Constants.LoginSessionLifetime)),
Expires = new DateTimeOffset(DateTime.UtcNow.Add(Duration.LoginSessionLifetime)),
Secure = true,
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Expand Down
8 changes: 5 additions & 3 deletions API/Controller/Tokens/TokenController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using OpenShock.API.Utils;
using OpenShock.Common;
using OpenShock.Common.Authentication.Attributes;
using OpenShock.Common.Constants;
using OpenShock.Common.Errors;
using OpenShock.Common.Models;
using OpenShock.Common.OpenShockDb;
Expand Down Expand Up @@ -108,7 +109,7 @@ public async Task<TokenCreatedResponse> CreateToken([FromBody] CreateTokenReques
var token = new ApiToken
{
UserId = CurrentUser.DbUser.Id,
Token = CryptoUtils.RandomString(64),
Token = CryptoUtils.RandomString(HardLimits.ApiKeyTokenMaxLength),
CreatedByIp = HttpContext.GetRemoteIP().ToString(),
Permissions = body.Permissions.Distinct().ToList(),
Id = Guid.NewGuid(),
Expand Down Expand Up @@ -150,9 +151,10 @@ public async Task<IActionResult> EditToken([FromRoute] Guid tokenId, [FromBody]

public class EditTokenRequest
{
[StringLength(64, ErrorMessage = "Name must be less than 64 characters")]
[StringLength(HardLimits.ApiKeyTokenMaxLength, MinimumLength = HardLimits.ApiKeyTokenMinLength, ErrorMessage = "API token length must be between {1} and {2}")]
public required string Name { get; set; }
[MaxLength(256, ErrorMessage = "You can only have 256 permissions, this is a hard limit")]

[MaxLength(HardLimits.ApiKeyMaxPermissions, ErrorMessage = "API token permissions must be between {1} and {2}")]
public List<PermissionType> Permissions { get; set; } = [PermissionType.Shockers_Use];
}

Expand Down
6 changes: 5 additions & 1 deletion API/Models/Requests/ChangeEmailRequest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
namespace OpenShock.API.Models.Requests;

using OpenShock.Common.DataAnnotations;

namespace OpenShock.API.Models.Requests;

public sealed class ChangeEmailRequest
{
[EmailAddress(true)]
public required string Email { get; set; }
}
8 changes: 7 additions & 1 deletion API/Models/Requests/ChangePasswordRequest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
namespace OpenShock.API.Models.Requests;
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.DataAnnotations;

namespace OpenShock.API.Models.Requests;

public sealed class ChangePasswordRequest
{
[Required(AllowEmptyStrings = false)]
public required string OldPassword { get; set; }

[Password(true)]
public required string NewPassword { get; set; }
}
7 changes: 6 additions & 1 deletion API/Models/Requests/ChangeUsernameRequest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
namespace OpenShock.API.Models.Requests;
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;
using OpenShock.Common.DataAnnotations;

namespace OpenShock.API.Models.Requests;

public sealed class ChangeUsernameRequest
{
[Username(true)]
public required string Username { get; init; }
}
3 changes: 2 additions & 1 deletion API/Models/Requests/CreateShareRequest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class CreateShareRequest
{
[MaxLength(128)] // Hard limit
[MaxLength(HardLimits.CreateShareRequestMaxShockers)]
public required IEnumerable<ShockerPermLimitPairWithId> Shockers { get; set; }
public Guid? User { get; set; } = null;
}
Expand Down
3 changes: 2 additions & 1 deletion API/Models/Requests/HubCreateRequest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class HubCreateRequest
{
[Required(AllowEmptyStrings = false)]
[StringLength(32, MinimumLength = 1)]
[StringLength(HardLimits.HubNameMaxLength, MinimumLength = HardLimits.HubNameMinLength)]
public required string Name { get; init; }
}
3 changes: 2 additions & 1 deletion API/Models/Requests/HubEditRequest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class HubEditRequest
{
[Required(AllowEmptyStrings = false)]
[StringLength(32, MinimumLength = 1)]
[StringLength(HardLimits.HubNameMaxLength, MinimumLength = HardLimits.HubNameMinLength)]
public required string Name { get; set; }
}
6 changes: 4 additions & 2 deletions API/Models/Requests/Login.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class Login
{
[MinLength(1)]
[Required(AllowEmptyStrings = false)]
public required string Password { get; set; }
[MinLength(1)]

[Required(AllowEmptyStrings = false)]
public required string Email { get; set; }
}
12 changes: 9 additions & 3 deletions API/Models/Requests/LoginV2.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class LoginV2
{
[Required(AllowEmptyStrings = false)] public required string Password { get; set; }
[Required(AllowEmptyStrings = false)] public required string Email { get; set; }
[Required(AllowEmptyStrings = false)] public required string TurnstileResponse { get; set; }
[Required(AllowEmptyStrings = false)]
public required string Password { get; set; }

[Required(AllowEmptyStrings = false)]
public required string Email { get; set; }

[Required(AllowEmptyStrings = false)]
public required string TurnstileResponse { get; set; }
}
5 changes: 4 additions & 1 deletion API/Models/Requests/NewShocker.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;
using OpenShock.Common.Models;

namespace OpenShock.API.Models.Requests;

public sealed class NewShocker
{
[StringLength(48, MinimumLength = 1)] public required string Name { get; set; }
[Required(AllowEmptyStrings = false)]
[StringLength(HardLimits.ShockerNameMaxLength, MinimumLength = HardLimits.ShockerNameMinLength)]
public required string Name { get; set; }
public required ushort RfId { get; set; }
public required Guid Device { get; set; }
public required ShockerModelType Model { get; set; }
Expand Down
7 changes: 6 additions & 1 deletion API/Models/Requests/ShareLinkCreate.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
namespace OpenShock.API.Models.Requests;
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

public sealed class ShareLinkCreate
{
[Required(AllowEmptyStrings = false)]
[StringLength(HardLimits.ShockerShareLinkNameMaxLength, MinimumLength = HardLimits.ShockerShareLinkNameMinLength)]
public required string Name { get; set; }
public DateTime? ExpiresOn { get; set; } = null;
}
3 changes: 2 additions & 1 deletion API/Models/Requests/ShareLinkEditShocker.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.API.Models.Response;
using OpenShock.Common;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Requests;

Expand All @@ -9,6 +10,6 @@ public sealed class ShareLinkEditShocker
public required ShockerPermissions Permissions { get; set; }
public required ShockerLimits Limits { get; set; }

[Range(Constants.MinControlDuration, Constants.MaxControlDuration)]
[Range(HardLimits.MinControlDuration, HardLimits.MaxControlDuration)]
public ushort? Cooldown { get; set; }
}
8 changes: 5 additions & 3 deletions API/Models/Requests/Signup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;
using OpenShock.Common.DataAnnotations;

namespace OpenShock.API.Models.Requests;
Expand All @@ -7,8 +7,10 @@ public sealed class SignUp
{
[Username(true)]
public required string Username { get; set; }
[StringLength(256, MinimumLength = 12)]

[Password(true)]
public required string Password { get; set; }
[EmailAddress]

[EmailAddress(true)]
public required string Email { get; set; }
}
13 changes: 8 additions & 5 deletions API/Models/Requests/SignupV2.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.DataAnnotations;
using OpenShock.Common.DataAnnotations;

namespace OpenShock.API.Models.Requests;

public sealed class SignUpV2
{
[Username(true)]
public required string Username { get; set; }
[StringLength(256, MinimumLength = 12)]

[Password(true)]
public required string Password { get; set; }
[EmailAddress]

[EmailAddress(true)]
public required string Email { get; set; }
[Required(AllowEmptyStrings = false)] public required string TurnstileResponse { get; set; }

[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = false)]
public required string TurnstileResponse { get; set; }
}
5 changes: 3 additions & 2 deletions API/Models/Response/ShockerLimits.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using OpenShock.Common;
using System.ComponentModel.DataAnnotations;
using OpenShock.Common.Constants;

namespace OpenShock.API.Models.Response;

public sealed class ShockerLimits
{
[Range(Constants.MinControlIntensity, Constants.MaxControlIntensity)]
[Range(HardLimits.MinControlIntensity, HardLimits.MaxControlIntensity)]
public required byte? Intensity { get; set; }

[Range(Constants.MinControlDuration, Constants.MaxControlDuration)]
[Range(HardLimits.MinControlDuration, HardLimits.MaxControlDuration)]
public required ushort? Duration { get; set; }
}
13 changes: 7 additions & 6 deletions API/Services/Account/AccountService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using OpenShock.API.Services.Email.Mailjet.Mail;
using OpenShock.API.Utils;
using OpenShock.Common;
using OpenShock.Common.Constants;
using OpenShock.Common.OpenShockDb;
using OpenShock.Common.Redis;
using OpenShock.Common.Utils;
Expand Down Expand Up @@ -131,8 +132,8 @@ await _loginSessions.InsertAsync(new LoginSession
Ip = loginContext.Ip,
PublicId = Guid.NewGuid(),
Created = DateTime.UtcNow,
Expires = DateTime.UtcNow.Add(Constants.LoginSessionLifetime),
}, Constants.LoginSessionLifetime);
Expires = DateTime.UtcNow.Add(Duration.LoginSessionLifetime),
}, Duration.LoginSessionLifetime);

return new Success<string>(randomSessionId);
}
Expand All @@ -141,7 +142,7 @@ await _loginSessions.InsertAsync(new LoginSession
public async Task<OneOf<Success, NotFound, SecretInvalid>> PasswordResetExists(Guid passwordResetId, string secret,
CancellationToken cancellationToken = default)
{
var validUntil = DateTime.UtcNow.Add(Constants.PasswordResetRequestLifetime);
var validUntil = DateTime.UtcNow.Add(Duration.PasswordResetRequestLifetime);
var reset = await _db.PasswordResets.FirstOrDefaultAsync(x =>
x.Id == passwordResetId && x.UsedOn == null && x.CreatedOn < validUntil,
cancellationToken: cancellationToken);
Expand All @@ -154,7 +155,7 @@ public async Task<OneOf<Success, NotFound, SecretInvalid>> PasswordResetExists(G
/// <inheritdoc />
public async Task<OneOf<Success, TooManyPasswordResets, NotFound>> CreatePasswordReset(string email)
{
var validUntil = DateTime.UtcNow.Add(Constants.PasswordResetRequestLifetime);
var validUntil = DateTime.UtcNow.Add(Duration.PasswordResetRequestLifetime);
var lowerCaseEmail = email.ToLowerInvariant();
var user = await _db.Users.Where(x => x.Email == lowerCaseEmail).Select(x => new
{
Expand Down Expand Up @@ -185,7 +186,7 @@ await _emailService.PasswordReset(new Contact(user.User.Email, user.User.Name),
public async Task<OneOf<Success, NotFound, SecretInvalid>> PasswordResetComplete(Guid passwordResetId,
string secret, string newPassword)
{
var validUntil = DateTime.UtcNow.Add(Constants.PasswordResetRequestLifetime);
var validUntil = DateTime.UtcNow.Add(Duration.PasswordResetRequestLifetime);

var reset = await _db.PasswordResets.Include(x => x.User).FirstOrDefaultAsync(x =>
x.Id == passwordResetId && x.UsedOn == null && x.CreatedOn < validUntil);
Expand Down Expand Up @@ -218,7 +219,7 @@ public async Task<OneOf<Success, Error<OneOf<UsernameTaken, UsernameError, Recen
ChangeUsername(Guid userId,
string username, bool ignoreLimit = false)
{
var cooldownSubtracted = DateTime.UtcNow.Subtract(Constants.NameChangeCooldown);
var cooldownSubtracted = DateTime.UtcNow.Subtract(Duration.NameChangeCooldown);
if (!ignoreLimit && await _db.UsersNameChanges.Where(x => x.UserId == userId && x.CreatedOn >= cooldownSubtracted).AnyAsync())
{
return new Error<OneOf<UsernameTaken, UsernameError, RecentlyChanged>>(new RecentlyChanged());
Expand Down
5 changes: 3 additions & 2 deletions Common.Tests/Geo/DistanceLookupTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OpenShock.Common.Geo;
using OpenShock.Common.Constants;
using OpenShock.Common.Geo;

namespace OpenShock.Common.Tests.Geo;

Expand Down Expand Up @@ -29,6 +30,6 @@ public async Task TryGetDistanceBetween_UnknownCountry(string str1, string str2)

// Assert
await Assert.That(result).IsFalse();
await Assert.That(distance).IsEqualTo(Constants.DistanceToAndromedaGalaxyInKm);
await Assert.That(distance).IsEqualTo(Distance.DistanceToAndromedaGalaxyInKm);
}
}
7 changes: 4 additions & 3 deletions Common/Authentication/Handlers/LoginSessionAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using OpenShock.Common.Authentication.Services;
using OpenShock.Common.Constants;
using OpenShock.Common.Errors;
using OpenShock.Common.Models;
using OpenShock.Common.OpenShockDb;
Expand Down Expand Up @@ -100,14 +101,14 @@ private async Task<AuthenticateResult> SessionAuth(string sessionKey)
// This can be removed at a later point, this is just for upgrade purposes
if(UpdateOlderLoginSessions(session)) await _userSessions.SaveAsync();

if (session.Expires!.Value < DateTime.UtcNow.Subtract(Constants.LoginSessionExpansionAfter))
if (session.Expires!.Value < DateTime.UtcNow.Subtract(Duration.LoginSessionExpansionAfter))
{
#pragma warning disable CS4014
LucTask.Run(async () =>
#pragma warning restore CS4014
{
session.Expires = DateTime.UtcNow.Add(Constants.LoginSessionLifetime);
await _userSessions.UpdateAsync(session, Constants.LoginSessionLifetime);
session.Expires = DateTime.UtcNow.Add(Duration.LoginSessionLifetime);
await _userSessions.UpdateAsync(session, Duration.LoginSessionLifetime);
});
}

Expand Down
Loading

0 comments on commit e5fa232

Please sign in to comment.