Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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