Localization - Part 2 (#2178)

* Changed language codes in the UI to be a list of all codes we will ever support.

* Converted actionables

* Fixed the GetLocales not using Intersect, but Union.

* Fixed some localization strings in backend when user doesn't exist.

Removed AllowAnonymous from reset-password, since it is a protected API

* Fixed all instances of anonymous APIs where Claim wouldn't work

* Keyed preference options and mixed misc localization issues

* Translations update from Hosted Weblate (#2177)

* Bump versions by dotnet-bump-version.

* Added translation using Weblate (Dutch)

* Bump versions by dotnet-bump-version.

* Translated using Weblate (Dutch)

Currently translated at 20.8% (33 of 158 strings)

Translation: Kavita/backend
Translate-URL: https://hosted.weblate.org/projects/kavita/backend/nl/

* Translated using Weblate (Spanish)

Currently translated at 1.4% (20 of 1371 strings)

Translation: Kavita/ui
Translate-URL: https://hosted.weblate.org/projects/kavita/ui/es/

* Translated using Weblate (Dutch)

Currently translated at 60.1% (95 of 158 strings)

Translation: Kavita/backend
Translate-URL: https://hosted.weblate.org/projects/kavita/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 60.1% (95 of 158 strings)

Translation: Kavita/backend
Translate-URL: https://hosted.weblate.org/projects/kavita/backend/nl/

* Added translation using Weblate (Dutch)

---------

Co-authored-by: Hans Kalisvaart <hans.kalisvaart@gmail.com>
Co-authored-by: Javier Barbero <javier.agustin.barbero@gmail.com>
Co-authored-by: Stijn <stijn.biemans@gmail.com>

---------

Co-authored-by: Weblate (bot) <hosted@weblate.org>
Co-authored-by: Hans Kalisvaart <hans.kalisvaart@gmail.com>
Co-authored-by: Javier Barbero <javier.agustin.barbero@gmail.com>
Co-authored-by: Stijn <stijn.biemans@gmail.com>
This commit is contained in:
Joe Milazzo 2023-08-03 17:51:32 -05:00 committed by GitHub
parent c7701bc729
commit 69532d45ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 2035 additions and 195 deletions

View file

@ -71,7 +71,6 @@ public class AccountController : BaseApiController
/// </summary>
/// <param name="resetPasswordDto"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("reset-password")]
public async Task<ActionResult> UpdatePassword(ResetPasswordDto resetPasswordDto)
{
@ -119,7 +118,7 @@ public class AccountController : BaseApiController
public async Task<ActionResult<UserDto>> RegisterFirstUser(RegisterDto registerDto)
{
var admins = await _userManager.GetUsersInRoleAsync("Admin");
if (admins.Count > 0) return BadRequest(await _localizationService.Translate(User.GetUserId(), "denied"));
if (admins.Count > 0) return BadRequest(await _localizationService.Get("en", "denied"));
try
{
@ -137,8 +136,8 @@ public class AccountController : BaseApiController
if (!result.Succeeded) return BadRequest(result.Errors);
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
if (string.IsNullOrEmpty(token)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "confirm-token-gen"));
if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "validate-email", token));
if (string.IsNullOrEmpty(token)) return BadRequest(await _localizationService.Get("en", "confirm-token-gen"));
if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Get("en", "validate-email", token));
var roleResult = await _userManager.AddToRoleAsync(user, PolicyConstants.AdminRole);
@ -165,7 +164,7 @@ public class AccountController : BaseApiController
await _unitOfWork.CommitAsync();
}
return BadRequest(await _localizationService.Translate(User.GetUserId(), "register-user"));
return BadRequest(await _localizationService.Get("en", "register-user"));
}
@ -182,9 +181,9 @@ public class AccountController : BaseApiController
.Include(u => u.UserPreferences)
.SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper());
if (user == null) return Unauthorized(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
if (user == null) return Unauthorized(await _localizationService.Get("en", "bad-credentials"));
var roles = await _userManager.GetRolesAsync(user);
if (!roles.Contains(PolicyConstants.LoginRole)) return Unauthorized(await _localizationService.Translate(User.GetUserId(), "disabled-account"));
if (!roles.Contains(PolicyConstants.LoginRole)) return Unauthorized(await _localizationService.Translate(user.Id, "disabled-account"));
var result = await _signInManager
.CheckPasswordSignInAsync(user, loginDto.Password, true);
@ -192,12 +191,12 @@ public class AccountController : BaseApiController
if (result.IsLockedOut)
{
await _userManager.UpdateSecurityStampAsync(user);
return Unauthorized(await _localizationService.Translate(User.GetUserId(), "locked-out"));
return Unauthorized(await _localizationService.Translate(user.Id, "locked-out"));
}
if (!result.Succeeded)
{
return Unauthorized(await _localizationService.Translate(User.GetUserId(), result.IsNotAllowed ? "confirm-email" : "bad-credentials"));
return Unauthorized(await _localizationService.Translate(user.Id, result.IsNotAllowed ? "confirm-email" : "bad-credentials"));
}
// Update LastActive on account
@ -258,7 +257,7 @@ public class AccountController : BaseApiController
var token = await _tokenService.ValidateRefreshToken(tokenRequestDto);
if (token == null)
{
return Unauthorized(new { message = await _localizationService.Translate(User.GetUserId(), "invalid-token") });
return Unauthorized(new { message = await _localizationService.Get("en", "invalid-token") });
}
return Ok(token);
@ -670,7 +669,7 @@ public class AccountController : BaseApiController
if (user == null)
{
_logger.LogInformation("confirm-email failed from invalid registered email: {Email}", dto.Email);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "invalid-email-confirmation"));
return BadRequest(await _localizationService.Get("en", "invalid-email-confirmation"));
}
// Validate Password and Username
@ -691,7 +690,7 @@ public class AccountController : BaseApiController
if (!await ConfirmEmailToken(dto.Token, user))
{
_logger.LogInformation("confirm-email failed from invalid token: {Token}", dto.Token);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "invalid-email-confirmation"));
return BadRequest(await _localizationService.Translate(user.Id, "invalid-email-confirmation"));
}
user.UserName = dto.Username;
@ -734,13 +733,13 @@ public class AccountController : BaseApiController
if (user == null)
{
_logger.LogInformation("confirm-email failed from invalid registered email: {Email}", dto.Email);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "invalid-email-confirmation"));
return BadRequest(await _localizationService.Get("en", "invalid-email-confirmation"));
}
if (!await ConfirmEmailToken(dto.Token, user))
{
_logger.LogInformation("confirm-email failed from invalid token: {Token}", dto.Token);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "invalid-email-confirmation"));
return BadRequest(await _localizationService.Translate(user.Id, "invalid-email-confirmation"));
}
_logger.LogInformation("User is updating email from {OldEmail} to {NewEmail}", user.Email, dto.Email);
@ -748,7 +747,7 @@ public class AccountController : BaseApiController
if (!result.Succeeded)
{
_logger.LogError("Unable to update email for users: {Errors}", result.Errors.Select(e => e.Description));
return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-user-email-update"));
return BadRequest(await _localizationService.Translate(user.Id, "generic-user-email-update"));
}
user.ConfirmationToken = null;
await _unitOfWork.CommitAsync();
@ -766,12 +765,12 @@ public class AccountController : BaseApiController
[HttpPost("confirm-password-reset")]
public async Task<ActionResult<string>> ConfirmForgotPassword(ConfirmPasswordResetDto dto)
{
var user = await _unitOfWork.UserRepository.GetUserByEmailAsync(dto.Email);
try
{
var user = await _unitOfWork.UserRepository.GetUserByEmailAsync(dto.Email);
if (user == null)
{
return BadRequest(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
return BadRequest(await _localizationService.Get("en", "bad-credentials"));
}
var result = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider,
@ -779,16 +778,16 @@ public class AccountController : BaseApiController
if (!result)
{
_logger.LogInformation("Unable to reset password, your email token is not correct: {@Dto}", dto);
return BadRequest(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
return BadRequest(await _localizationService.Translate(user.Id, "bad-credentials"));
}
var errors = await _accountService.ChangeUserPassword(user, dto.Password);
return errors.Any() ? BadRequest(errors) : Ok(await _localizationService.Translate(User.GetUserId(), "password-updated"));
return errors.Any() ? BadRequest(errors) : Ok(await _localizationService.Translate(user.Id, "password-updated"));
}
catch (Exception ex)
{
_logger.LogError(ex, "There was an unexpected error when confirming new password");
return BadRequest("generic-password-update");
return BadRequest(await _localizationService.Translate(user.Id, "generic-password-update"));
}
}
@ -807,15 +806,15 @@ public class AccountController : BaseApiController
if (user == null)
{
_logger.LogError("There are no users with email: {Email} but user is requesting password reset", email);
return Ok(await _localizationService.Translate(User.GetUserId(), "forgot-password-generic"));
return Ok(await _localizationService.Get("en", "forgot-password-generic"));
}
var roles = await _userManager.GetRolesAsync(user);
if (!roles.Any(r => r is PolicyConstants.AdminRole or PolicyConstants.ChangePasswordRole))
return Unauthorized(await _localizationService.Translate(User.GetUserId(), "permission-denied"));
return Unauthorized(await _localizationService.Translate(user.Id, "permission-denied"));
if (string.IsNullOrEmpty(user.Email) || !user.EmailConfirmed)
return BadRequest(await _localizationService.Translate(User.GetUserId(), "confirm-email"));
return BadRequest(await _localizationService.Translate(user.Id, "confirm-email"));
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var emailLink = await _accountService.GenerateEmailLink(Request, token, "confirm-reset-password", user.Email);
@ -828,10 +827,10 @@ public class AccountController : BaseApiController
ServerConfirmationLink = emailLink,
InstallId = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallId)).Value
});
return Ok(await _localizationService.Translate(User.GetUserId(), "email-sent"));
return Ok(await _localizationService.Translate(user.Id, "email-sent"));
}
return Ok(await _localizationService.Translate(User.GetUserId(), "not-accessible-password"));
return Ok(await _localizationService.Translate(user.Id, "not-accessible-password"));
}
[HttpGet("email-confirmed")]
@ -848,12 +847,12 @@ public class AccountController : BaseApiController
public async Task<ActionResult<UserDto>> ConfirmMigrationEmail(ConfirmMigrationEmailDto dto)
{
var user = await _unitOfWork.UserRepository.GetUserByEmailAsync(dto.Email);
if (user == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
if (user == null) return BadRequest(await _localizationService.Get("en", "bad-credentials"));
if (!await ConfirmEmailToken(dto.Token, user))
{
_logger.LogInformation("confirm-migration-email email token is invalid");
return BadRequest(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
return BadRequest(await _localizationService.Translate(user.Id, "bad-credentials"));
}
await _unitOfWork.CommitAsync();
@ -884,12 +883,12 @@ public class AccountController : BaseApiController
public async Task<ActionResult<string>> ResendConfirmationSendEmail([FromQuery] int userId)
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(userId);
if (user == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "no-user"));
if (user == null) return BadRequest(await _localizationService.Get("en", "no-user"));
if (string.IsNullOrEmpty(user.Email))
return BadRequest(
await _localizationService.Translate(User.GetUserId(), "user-migration-needed"));
if (user.EmailConfirmed) return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-confirmed"));
await _localizationService.Translate(user.Id, "user-migration-needed"));
if (user.EmailConfirmed) return BadRequest(await _localizationService.Translate(user.Id, "user-already-confirmed"));
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var emailLink = await _accountService.GenerateEmailLink(Request, token, "confirm-email", user.Email);
@ -910,12 +909,12 @@ public class AccountController : BaseApiController
catch (Exception ex)
{
_logger.LogError(ex, "There was an issue resending invite email");
return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-invite-email"));
return BadRequest(await _localizationService.Translate(user.Id, "generic-invite-email"));
}
return Ok(emailLink);
}
return Ok(await _localizationService.Translate(User.GetUserId(), "not-accessible"));
return Ok(await _localizationService.Translate(user.Id, "not-accessible"));
}
/// <summary>
@ -929,7 +928,7 @@ public class AccountController : BaseApiController
{
// If there is an admin account already, return
var users = await _unitOfWork.UserRepository.GetAdminUsersAsync();
if (users.Any()) return BadRequest(await _localizationService.Translate(User.GetUserId(), "admin-already-exists"));
if (users.Any()) return BadRequest(await _localizationService.Get("en", "admin-already-exists"));
// Check if there is an existing invite
var emailValidationErrors = await _accountService.ValidateEmail(dto.Email);
@ -937,27 +936,27 @@ public class AccountController : BaseApiController
{
var invitedUser = await _unitOfWork.UserRepository.GetUserByEmailAsync(dto.Email);
if (await _userManager.IsEmailConfirmedAsync(invitedUser!))
return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-registered", invitedUser!.UserName));
return BadRequest(await _localizationService.Get("en", "user-already-registered", invitedUser!.UserName));
_logger.LogInformation("A user is attempting to login, but hasn't accepted email invite");
return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-invited"));
return BadRequest(await _localizationService.Get("en", "user-already-invited"));
}
var user = await _userManager.Users
.Include(u => u.UserPreferences)
.SingleOrDefaultAsync(x => x.NormalizedUserName == dto.Username.ToUpper());
if (user == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "invalid-username"));
if (user == null) return BadRequest(await _localizationService.Get("en", "invalid-username"));
var validPassword = await _signInManager.UserManager.CheckPasswordAsync(user, dto.Password);
if (!validPassword) return BadRequest(await _localizationService.Translate(User.GetUserId(), "bad-credentials"));
if (!validPassword) return BadRequest(await _localizationService.Get("en", "bad-credentials"));
try
{
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
user.Email = dto.Email;
if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Translate(User.GetUserId(), "critical-email-migration"));
if (!await ConfirmEmailToken(token, user)) return BadRequest(await _localizationService.Get("en", "critical-email-migration"));
_unitOfWork.UserRepository.Update(user);
await _unitOfWork.CommitAsync();
@ -971,7 +970,7 @@ public class AccountController : BaseApiController
await _unitOfWork.CommitAsync();
}
return BadRequest(await _localizationService.Translate(User.GetUserId(), "critical-email-migration"));
return BadRequest(await _localizationService.Get("en", "critical-email-migration"));
}
@ -981,8 +980,6 @@ public class AccountController : BaseApiController
var result = await _userManager.ConfirmEmailAsync(user, token);
if (result.Succeeded) return true;
_logger.LogCritical("[Account] Email validation failed");
if (!result.Errors.Any()) return false;