From c197a330f3d66ca2c1634c047e7c9f2b116e082c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 25 Feb 2017 22:41:49 +0100 Subject: [PATCH 1/2] #1073 Add delay to email recovery command - Add configurable cooldown period after sending an email for /email recovery - Change ExpiringMap to remove expired entries (like ExpiringSet) - Create method to translate durations via the messages file --- .../executable/email/RecoverEmailCommand.java | 49 ++++++++++- .../fr/xephi/authme/message/MessageKey.java | 30 ++++++- .../fr/xephi/authme/message/Messages.java | 34 ++++++++ .../settings/properties/SecuritySettings.java | 7 ++ src/main/java/fr/xephi/authme/util/Utils.java | 33 -------- .../authme/util/expiring/ExpiringMap.java | 10 ++- .../authme/util/expiring/ExpiringSet.java | 11 ++- .../authme/util/expiring/TimedCounter.java | 4 +- .../email/RecoverEmailCommandTest.java | 83 +++++++++++++++---- .../message/MessagesIntegrationTest.java | 24 ++++++ .../authme/util/expiring/ExpiringSetTest.java | 39 +++++++-- 11 files changed, 252 insertions(+), 72 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java index eb188f790..b3fb3b62b 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java @@ -5,24 +5,31 @@ import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.message.Messages; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.RecoveryCodeService; +import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.util.RandomStringUtils; +import fr.xephi.authme.util.expiring.Duration; +import fr.xephi.authme.util.expiring.ExpiringSet; import org.bukkit.entity.Player; +import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.List; +import java.util.concurrent.TimeUnit; import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH; /** * Command for password recovery by email. */ -public class RecoverEmailCommand extends PlayerCommand { +public class RecoverEmailCommand extends PlayerCommand implements Reloadable { @Inject private PasswordSecurity passwordSecurity; @@ -42,8 +49,19 @@ public class RecoverEmailCommand extends PlayerCommand { @Inject private RecoveryCodeService recoveryCodeService; + @Inject + private Messages messages; + + private ExpiringSet emailCooldown; + + @PostConstruct + private void initEmailCooldownSet() { + emailCooldown = new ExpiringSet<>( + commonService.getProperty(SecuritySettings.EMAIL_RECOVERY_COOLDOWN_SECONDS), TimeUnit.SECONDS); + } + @Override - public void runCommand(Player player, List arguments) { + protected void runCommand(Player player, List arguments) { final String playerMail = arguments.get(0); final String playerName = player.getName(); @@ -78,15 +96,29 @@ public class RecoverEmailCommand extends PlayerCommand { processRecoveryCode(player, arguments.get(1), email); } } else { - generateAndSendNewPassword(player, email); + boolean maySendMail = checkEmailCooldown(player); + if (maySendMail) { + generateAndSendNewPassword(player, email); + } } } + @Override + public void reload() { + emailCooldown.setExpiration( + commonService.getProperty(SecuritySettings.EMAIL_RECOVERY_COOLDOWN_SECONDS), TimeUnit.SECONDS); + } + private void createAndSendRecoveryCode(Player player, String email) { + if (!checkEmailCooldown(player)) { + return; + } + String recoveryCode = recoveryCodeService.generateCode(player.getName()); boolean couldSendMail = emailService.sendRecoveryCode(player.getName(), email, recoveryCode); if (couldSendMail) { commonService.send(player, MessageKey.RECOVERY_CODE_SENT); + emailCooldown.add(player.getName().toLowerCase()); } else { commonService.send(player, MessageKey.EMAIL_SEND_FAILURE); } @@ -111,8 +143,19 @@ public class RecoverEmailCommand extends PlayerCommand { boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass); if (couldSendMail) { commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + emailCooldown.add(player.getName().toLowerCase()); } else { commonService.send(player, MessageKey.EMAIL_SEND_FAILURE); } } + + private boolean checkEmailCooldown(Player player) { + Duration waitDuration = emailCooldown.getExpiration(player.getName().toLowerCase()); + if (waitDuration.getDuration() > 0) { + String durationText = messages.formatDuration(waitDuration); + messages.send(player, MessageKey.EMAIL_COOLDOWN_ERROR, durationText); + return false; + } + return true; + } } diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index 7546a89c0..e8c3939a9 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -225,7 +225,35 @@ public enum MessageKey { RECOVERY_CODE_SENT("recovery_code_sent"), /** The recovery code is not correct! Use "/email recovery [email]" to generate a new one */ - INCORRECT_RECOVERY_CODE("recovery_code_incorrect"); + INCORRECT_RECOVERY_CODE("recovery_code_incorrect"), + + /** An email was already sent recently. You must wait %time before you can send a new one. */ + EMAIL_COOLDOWN_ERROR("email_cooldown_error", "%time"), + + /** second */ + SECOND("second"), + + /** seconds */ + SECONDS("seconds"), + + /** minute */ + MINUTE("minute"), + + /** minutes */ + MINUTES("minutes"), + + /** hour */ + HOUR("hour"), + + /** hours */ + HOURS("hours"), + + /** day */ + DAY("day"), + + /** days */ + DAYS("days"); + private String key; private String[] tags; diff --git a/src/main/java/fr/xephi/authme/message/Messages.java b/src/main/java/fr/xephi/authme/message/Messages.java index 5d777ab83..d7fdcec89 100644 --- a/src/main/java/fr/xephi/authme/message/Messages.java +++ b/src/main/java/fr/xephi/authme/message/Messages.java @@ -1,11 +1,15 @@ package fr.xephi.authme.message; +import com.google.common.collect.ImmutableMap; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.Reloadable; +import fr.xephi.authme.util.expiring.Duration; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import javax.inject.Inject; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * Class for retrieving and sending translatable messages to players. @@ -15,6 +19,20 @@ public class Messages implements Reloadable { // Custom Authme tag replaced to new line private static final String NEWLINE_TAG = "%nl%"; + /** Contains the keys of the singular messages for time units. */ + private static final Map TIME_UNIT_SINGULARS = ImmutableMap.builder() + .put(TimeUnit.SECONDS, MessageKey.SECOND) + .put(TimeUnit.MINUTES, MessageKey.MINUTE) + .put(TimeUnit.HOURS, MessageKey.HOUR) + .put(TimeUnit.DAYS, MessageKey.DAY).build(); + + /** Contains the keys of the plural messages for time units. */ + private static final Map TIME_UNIT_PLURALS = ImmutableMap.builder() + .put(TimeUnit.SECONDS, MessageKey.SECONDS) + .put(TimeUnit.MINUTES, MessageKey.MINUTES) + .put(TimeUnit.HOURS, MessageKey.HOURS) + .put(TimeUnit.DAYS, MessageKey.DAYS).build(); + private final MessageFileHandlerProvider messageFileHandlerProvider; private MessageFileHandler messageFileHandler; @@ -71,6 +89,22 @@ public class Messages implements Reloadable { return message.split("\n"); } + /** + * Returns the textual representation for the given duration. + * Note that this class only supports the time units days, hour, minutes and seconds. + * + * @param duration the duration to build a text of + * @return text of the duration + */ + public String formatDuration(Duration duration) { + long value = duration.getDuration(); + MessageKey timeUnitKey = value == 1 + ? TIME_UNIT_SINGULARS.get(duration.getTimeUnit()) + : TIME_UNIT_PLURALS.get(duration.getTimeUnit()); + + return value + " " + retrieveMessage(timeUnitKey); + } + /** * Retrieve the message from the text file. * diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index daed1a8c9..496fb3b2b 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -114,6 +114,13 @@ public class SecuritySettings implements SettingsHolder { public static final Property RECOVERY_CODE_HOURS_VALID = newProperty("Security.recoveryCode.validForHours", 4); + @Comment({ + "Seconds a user has to wait for before a password recovery mail may be sent again", + "This prevents an attacker from abusing AuthMe's email feature." + }) + public static final Property EMAIL_RECOVERY_COOLDOWN_SECONDS = + newProperty("Security.emailRecovery.cooldown", 60); + private SecuritySettings() { } diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index e7ec1657a..b7628147b 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -3,7 +3,6 @@ package fr.xephi.authme.util; import fr.xephi.authme.ConsoleLogger; import java.util.Collection; -import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; /** @@ -71,36 +70,4 @@ public final class Utils { return Runtime.getRuntime().availableProcessors(); } - public static Duration convertMillisToSuitableUnit(long duration) { - TimeUnit targetUnit; - if (duration > 1000L * 60L * 60L * 24L) { - targetUnit = TimeUnit.DAYS; - } else if (duration > 1000L * 60L * 60L) { - targetUnit = TimeUnit.HOURS; - } else if (duration > 1000L * 60L) { - targetUnit = TimeUnit.MINUTES; - } else if (duration > 1000L) { - targetUnit = TimeUnit.SECONDS; - } else { - targetUnit = TimeUnit.MILLISECONDS; - } - - return new Duration(targetUnit, duration); - } - - public static final class Duration { - - private final long duration; - private final TimeUnit unit; - - Duration(TimeUnit targetUnit, long durationMillis) { - this(targetUnit, durationMillis, TimeUnit.MILLISECONDS); - } - - Duration(TimeUnit targetUnit, long sourceDuration, TimeUnit sourceUnit) { - this.duration = targetUnit.convert(sourceDuration, sourceUnit); - this.unit = targetUnit; - } - } - } diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java b/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java index 894b6486e..e920805c2 100644 --- a/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java +++ b/src/main/java/fr/xephi/authme/util/expiring/ExpiringMap.java @@ -46,7 +46,13 @@ public class ExpiringMap { */ public V get(K key) { ExpiringEntry value = entries.get(key); - return value == null ? null : value.getValue(); + if (value == null) { + return null; + } else if (System.currentTimeMillis() > value.getExpiration()) { + entries.remove(key); + return null; + } + return value.getValue(); } /** @@ -115,7 +121,7 @@ public class ExpiringMap { } V getValue() { - return System.currentTimeMillis() > expiration ? null : value; + return value; } long getExpiration() { diff --git a/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java b/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java index 7e711673e..fea8fb313 100644 --- a/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java +++ b/src/main/java/fr/xephi/authme/util/expiring/ExpiringSet.java @@ -83,23 +83,22 @@ public class ExpiringSet { /** * Returns the duration of the entry until it expires (provided it is not removed or re-added). - * If the entry does not exist, -1 is returned. + * If the entry does not exist, a duration of -1 seconds is returned. * * @param entry the entry whose duration before it expires should be returned - * @param unit the unit in which to return the duration * @return duration the entry will remain in the set (if there are not modifications) */ - public long getExpiration(E entry, TimeUnit unit) { + public Duration getExpiration(E entry) { Long expiration = entries.get(entry); if (expiration == null) { - return -1; + return new Duration(-1, TimeUnit.SECONDS); } long stillPresentMillis = expiration - System.currentTimeMillis(); if (stillPresentMillis < 0) { entries.remove(entry); - return -1; + return new Duration(-1, TimeUnit.SECONDS); } - return unit.convert(stillPresentMillis, TimeUnit.MILLISECONDS); + return Duration.createWithSuitableUnit(stillPresentMillis, TimeUnit.MILLISECONDS); } /** diff --git a/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java b/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java index 67839294c..c3ae908cd 100644 --- a/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java +++ b/src/main/java/fr/xephi/authme/util/expiring/TimedCounter.java @@ -1,6 +1,5 @@ package fr.xephi.authme.util.expiring; -import java.util.Objects; import java.util.concurrent.TimeUnit; /** @@ -42,9 +41,10 @@ public class TimedCounter extends ExpiringMap { * @return the total of all valid entries */ public int total() { + long currentTime = System.currentTimeMillis(); return entries.values().stream() + .filter(entry -> currentTime <= entry.getExpiration()) .map(ExpiringEntry::getValue) - .filter(Objects::nonNull) .reduce(0, Integer::sum); } } diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 556a10331..5b1020780 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -1,29 +1,39 @@ package fr.xephi.authme.command.executable.email; +import ch.jalu.injector.testing.BeforeInjecting; +import ch.jalu.injector.testing.DelayedInjectionRunner; +import ch.jalu.injector.testing.InjectDelayed; import fr.xephi.authme.TestHelper; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.mail.EmailService; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.message.Messages; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.RecoveryCodeService; import fr.xephi.authme.settings.properties.EmailSettings; +import fr.xephi.authme.settings.properties.SecuritySettings; +import fr.xephi.authme.util.expiring.Duration; import org.bukkit.entity.Player; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.Mockito; import java.util.Arrays; import java.util.Collections; +import java.util.concurrent.TimeUnit; import static fr.xephi.authme.AuthMeMatchers.stringWithLength; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -38,19 +48,19 @@ import static org.mockito.Mockito.verifyZeroInteractions; /** * Test for {@link RecoverEmailCommand}. */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(DelayedInjectionRunner.class) public class RecoverEmailCommandTest { private static final String DEFAULT_EMAIL = "your@email.com"; - @InjectMocks + @InjectDelayed private RecoverEmailCommand command; @Mock private PasswordSecurity passwordSecurity; @Mock - private CommonService commandService; + private CommonService commonService; @Mock private DataSource dataSource; @@ -64,11 +74,19 @@ public class RecoverEmailCommandTest { @Mock private RecoveryCodeService recoveryCodeService; + @Mock + private Messages messages; + @BeforeClass public static void initLogger() { TestHelper.setupLogger(); } + @BeforeInjecting + public void initSettings() { + given(commonService.getProperty(SecuritySettings.EMAIL_RECOVERY_COOLDOWN_SECONDS)).willReturn(40); + } + @Test public void shouldHandleMissingMailProperties() { // given @@ -79,7 +97,7 @@ public class RecoverEmailCommandTest { command.executeCommand(sender, Collections.singletonList("some@email.tld")); // then - verify(commandService).send(sender, MessageKey.INCOMPLETE_EMAIL_SETTINGS); + verify(commonService).send(sender, MessageKey.INCOMPLETE_EMAIL_SETTINGS); verifyZeroInteractions(dataSource, passwordSecurity); } @@ -98,7 +116,7 @@ public class RecoverEmailCommandTest { // then verify(emailService).hasAllInformation(); verifyZeroInteractions(dataSource); - verify(commandService).send(sender, MessageKey.ALREADY_LOGGED_IN_ERROR); + verify(commonService).send(sender, MessageKey.ALREADY_LOGGED_IN_ERROR); } @Test @@ -118,7 +136,7 @@ public class RecoverEmailCommandTest { verify(emailService).hasAllInformation(); verify(dataSource).getAuth(name); verifyNoMoreInteractions(dataSource); - verify(commandService).send(sender, MessageKey.USAGE_REGISTER); + verify(commonService).send(sender, MessageKey.USAGE_REGISTER); } @Test @@ -138,7 +156,7 @@ public class RecoverEmailCommandTest { verify(emailService).hasAllInformation(); verify(dataSource).getAuth(name); verifyNoMoreInteractions(dataSource); - verify(commandService).send(sender, MessageKey.INVALID_EMAIL); + verify(commonService).send(sender, MessageKey.INVALID_EMAIL); } @Test @@ -158,7 +176,7 @@ public class RecoverEmailCommandTest { verify(emailService).hasAllInformation(); verify(dataSource).getAuth(name); verifyNoMoreInteractions(dataSource); - verify(commandService).send(sender, MessageKey.INVALID_EMAIL); + verify(commonService).send(sender, MessageKey.INVALID_EMAIL); } @Test @@ -183,7 +201,7 @@ public class RecoverEmailCommandTest { verify(emailService).hasAllInformation(); verify(dataSource).getAuth(name); verify(recoveryCodeService).generateCode(name); - verify(commandService).send(sender, MessageKey.RECOVERY_CODE_SENT); + verify(commonService).send(sender, MessageKey.RECOVERY_CODE_SENT); verify(emailService).sendRecoveryCode(name, email, code); } @@ -207,7 +225,7 @@ public class RecoverEmailCommandTest { // then verify(emailService).hasAllInformation(); verify(dataSource, only()).getAuth(name); - verify(commandService).send(sender, MessageKey.INCORRECT_RECOVERY_CODE); + verify(commonService).send(sender, MessageKey.INCORRECT_RECOVERY_CODE); verifyNoMoreInteractions(emailService); } @@ -224,7 +242,7 @@ public class RecoverEmailCommandTest { String code = "A6EF3AC8"; PlayerAuth auth = newAuthWithEmail(email); given(dataSource.getAuth(name)).willReturn(auth); - given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); + given(commonService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); given(passwordSecurity.computeHash(anyString(), eq(name))) .willAnswer(invocation -> new HashedPassword(invocation.getArgument(0))); given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(true); @@ -243,7 +261,7 @@ public class RecoverEmailCommandTest { verify(dataSource).updatePassword(eq(name), any(HashedPassword.class)); verify(recoveryCodeService).removeCode(name); verify(emailService).sendPasswordMail(name, email, generatedPassword); - verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + verify(commonService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); } @Test @@ -258,7 +276,7 @@ public class RecoverEmailCommandTest { String email = "shark@example.org"; PlayerAuth auth = newAuthWithEmail(email); given(dataSource.getAuth(name)).willReturn(auth); - given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); + given(commonService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); given(passwordSecurity.computeHash(anyString(), eq(name))) .willAnswer(invocation -> new HashedPassword(invocation.getArgument(0))); given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(false); @@ -275,7 +293,40 @@ public class RecoverEmailCommandTest { assertThat(generatedPassword, stringWithLength(20)); verify(dataSource).updatePassword(eq(name), any(HashedPassword.class)); verify(emailService).sendPasswordMail(name, email, generatedPassword); - verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + verify(commonService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + } + + @Test + public void shouldNotSendEmailIfCooldownCheckFails() { + // given + String name = "feverRay"; + Player sender = mock(Player.class); + given(sender.getName()).willReturn(name); + given(emailService.hasAllInformation()).willReturn(true); + given(emailService.sendRecoveryCode(anyString(), anyString(), anyString())).willReturn(true); + given(playerCache.isAuthenticated(name)).willReturn(false); + String email = "mymail@example.org"; + PlayerAuth auth = newAuthWithEmail(email); + given(dataSource.getAuth(name)).willReturn(auth); + given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(true); + given(recoveryCodeService.generateCode(anyString())).willReturn("Code"); + // Trigger sending of recovery code + command.executeCommand(sender, Collections.singletonList(email)); + + Mockito.reset(emailService, commonService); + given(emailService.hasAllInformation()).willReturn(true); + given(messages.formatDuration(any(Duration.class))).willReturn("8 minutes"); + + // when + command.executeCommand(sender, Collections.singletonList(email)); + + // then + verify(emailService, only()).hasAllInformation(); + ArgumentCaptor durationCaptor = ArgumentCaptor.forClass(Duration.class); + verify(messages).formatDuration(durationCaptor.capture()); + assertThat(durationCaptor.getValue().getDuration(), both(lessThan(41L)).and(greaterThan(36L))); + assertThat(durationCaptor.getValue().getTimeUnit(), equalTo(TimeUnit.SECONDS)); + verify(messages).send(sender, MessageKey.EMAIL_COOLDOWN_ERROR, "8 minutes"); } diff --git a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java index 94fe9a0df..8f48fffec 100644 --- a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java @@ -1,7 +1,9 @@ package fr.xephi.authme.message; +import com.google.common.collect.ImmutableMap; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.util.expiring.Duration; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.junit.Before; @@ -11,6 +13,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import java.io.File; +import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.logging.Logger; @@ -230,6 +234,26 @@ public class MessagesIntegrationTest { assertThat(result, equalTo("Use /captcha 24680 to solve the captcha")); } + @Test + public void shouldFormatDurationObjects() { + // given + Map expectedTexts = ImmutableMap.builder() + .put(new Duration(1, TimeUnit.SECONDS), "1 second") + .put(new Duration(12, TimeUnit.SECONDS), "12 seconds") + .put(new Duration(1, TimeUnit.MINUTES), "1 minute") + .put(new Duration(0, TimeUnit.MINUTES), "0 minutes") + .put(new Duration(1, TimeUnit.HOURS), "1 hour") + .put(new Duration(-4, TimeUnit.HOURS), "-4 hours") + .put(new Duration(1, TimeUnit.DAYS), "1 day") + .put(new Duration(44, TimeUnit.DAYS), "44 days") + .build(); + + // when / then + for (Map.Entry entry : expectedTexts.entrySet()) { + assertThat(messages.formatDuration(entry.getKey()), equalTo(entry.getValue())); + } + } + @SuppressWarnings("unchecked") private static MessageFileHandlerProvider providerReturning(File file, String defaultFile) { MessageFileHandlerProvider handler = mock(MessageFileHandlerProvider.class); diff --git a/src/test/java/fr/xephi/authme/util/expiring/ExpiringSetTest.java b/src/test/java/fr/xephi/authme/util/expiring/ExpiringSetTest.java index 15a55aa09..42180ab26 100644 --- a/src/test/java/fr/xephi/authme/util/expiring/ExpiringSetTest.java +++ b/src/test/java/fr/xephi/authme/util/expiring/ExpiringSetTest.java @@ -4,7 +4,6 @@ import org.junit.Test; import java.util.concurrent.TimeUnit; -import static org.hamcrest.Matchers.either; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -97,14 +96,31 @@ public class ExpiringSetTest { set.add("my entry"); // when - long expiresInHours = set.getExpiration("my entry", TimeUnit.HOURS); - long expiresInMinutes = set.getExpiration("my entry", TimeUnit.MINUTES); - long unknownExpires = set.getExpiration("bogus", TimeUnit.SECONDS); + Duration expiration = set.getExpiration("my entry"); + Duration unknownExpiration = set.getExpiration("bogus"); // then - assertThat(expiresInHours, equalTo(2L)); - assertThat(expiresInMinutes, either(equalTo(122L)).or(equalTo(123L))); - assertThat(unknownExpires, equalTo(-1L)); + assertIsDuration(expiration, 2, TimeUnit.HOURS); + assertIsDuration(unknownExpiration, -1, TimeUnit.SECONDS); + } + + @Test + public void shouldReturnExpirationInSuitableUnits() { + // given + ExpiringSet set = new ExpiringSet<>(601, TimeUnit.SECONDS); + set.add(12); + set.setExpiration(49, TimeUnit.HOURS); + set.add(23); + + // when + Duration expiration12 = set.getExpiration(12); + Duration expiration23 = set.getExpiration(23); + Duration expectedUnknown = set.getExpiration(-100); + + // then + assertIsDuration(expiration12, 10, TimeUnit.MINUTES); + assertIsDuration(expiration23, 2, TimeUnit.DAYS); + assertIsDuration(expectedUnknown, -1, TimeUnit.SECONDS); } @Test @@ -114,9 +130,14 @@ public class ExpiringSetTest { set.add(23); // when - long expiresInSeconds = set.getExpiration(23, TimeUnit.SECONDS); + Duration expiration = set.getExpiration(23); // then - assertThat(expiresInSeconds, equalTo(-1L)); + assertIsDuration(expiration, -1, TimeUnit.SECONDS); + } + + private static void assertIsDuration(Duration duration, long expectedDuration, TimeUnit expectedUnit) { + assertThat(duration.getTimeUnit(), equalTo(expectedUnit)); + assertThat(duration.getDuration(), equalTo(expectedDuration)); } } From 33c4a4690fe7063199fd197f9c3fd49d11238a9f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 25 Feb 2017 22:42:23 +0100 Subject: [PATCH 2/2] #1073 Email recovery delay: update project files following new messages & config --- docs/config.md | 10 +++- docs/translations.md | 59 +++++++++---------- src/main/resources/messages/messages_bg.yml | 13 +++- src/main/resources/messages/messages_br.yml | 11 ++++ src/main/resources/messages/messages_cz.yml | 11 ++++ src/main/resources/messages/messages_de.yml | 11 ++++ src/main/resources/messages/messages_en.yml | 11 ++++ src/main/resources/messages/messages_es.yml | 11 ++++ src/main/resources/messages/messages_eu.yml | 15 ++++- src/main/resources/messages/messages_fi.yml | 13 +++- src/main/resources/messages/messages_fr.yml | 11 ++++ src/main/resources/messages/messages_gl.yml | 13 +++- src/main/resources/messages/messages_hu.yml | 11 ++++ src/main/resources/messages/messages_id.yml | 13 +++- src/main/resources/messages/messages_it.yml | 11 ++++ src/main/resources/messages/messages_ko.yml | 13 +++- src/main/resources/messages/messages_lt.yml | 13 +++- src/main/resources/messages/messages_nl.yml | 11 ++++ src/main/resources/messages/messages_pl.yml | 11 ++++ src/main/resources/messages/messages_pt.yml | 13 +++- src/main/resources/messages/messages_ro.yml | 11 ++++ src/main/resources/messages/messages_ru.yml | 11 ++++ src/main/resources/messages/messages_sk.yml | 15 ++++- src/main/resources/messages/messages_tr.yml | 13 +++- src/main/resources/messages/messages_uk.yml | 13 +++- src/main/resources/messages/messages_vn.yml | 11 ++++ src/main/resources/messages/messages_zhcn.yml | 11 ++++ src/main/resources/messages/messages_zhhk.yml | 13 +++- src/main/resources/messages/messages_zhmc.yml | 11 ++++ src/main/resources/messages/messages_zhtw.yml | 13 +++- 30 files changed, 360 insertions(+), 47 deletions(-) diff --git a/docs/config.md b/docs/config.md index 4b3396b5b..ff2d54fb4 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -422,6 +422,8 @@ Security: maxLoginTry: 5 # Captcha length captchaLength: 5 + # Minutes after which login attempts count is reset for a player + captchaCountReset: 60 tempban: # Tempban a user's IP address if they enter the wrong password too many times enableTempban: false @@ -438,6 +440,10 @@ Security: length: 8 # How many hours is a recovery code valid for? validForHours: 4 + emailRecovery: + # Seconds a user has to wait for before a password recovery mail may be sent again + # This prevents an attacker from abusing AuthMe's email feature. + cooldown: 60 BackupSystem: # Enable or disable automatic backup ActivateBackup: false @@ -454,4 +460,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Feb 05 13:46:19 CET 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Feb 25 21:59:18 CET 2017 diff --git a/docs/translations.md b/docs/translations.md index dee35ed79..a4bc104ba 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code @@ -8,35 +8,34 @@ in your config.yml to use the language, or use another language code to start a Code | Language | Translated |   ---- | -------- | ---------: | ------ [en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | bar -[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 69% | bar -[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | bar -[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 100% | bar -[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 100% | bar -[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | bar -[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 62% | bar -[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 66% | bar -[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 100% | bar -[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 70% | bar -[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 99% | bar -[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 70% | bar -[it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | bar -[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 72% | bar -[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 53% | bar -[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 77% | bar -[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | bar -[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 86% | bar -[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 99% | bar -[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 99% | bar -[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 46% | bar -[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 81% | bar -[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 93% | bar -[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 100% | bar -[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 81% | bar -[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 81% | bar -[zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 96% | bar -[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 81% | bar - +[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 61% | bar +[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 89% | bar +[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 89% | bar +[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 89% | bar +[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 89% | bar +[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 55% | bar +[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 59% | bar +[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 89% | bar +[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 63% | bar +[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 88% | bar +[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 63% | bar +[it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 89% | bar +[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 64% | bar +[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Lithuanian | 47% | bar +[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 89% | bar +[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 89% | bar +[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 77% | bar +[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 88% | bar +[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 89% | bar +[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 41% | bar +[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 72% | bar +[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 83% | bar +[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 89% | bar +[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 89% | bar +[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 72% | bar +[zhmc](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhmc.yml) | Chinese (Macau) | 86% | bar +[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 72% | bar --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Wed Jan 11 21:24:50 CET 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Feb 25 21:59:17 CET 2017 diff --git a/src/main/resources/messages/messages_bg.yml b/src/main/resources/messages/messages_bg.yml index 977e8eaf5..38e79face 100644 --- a/src/main/resources/messages/messages_bg.yml +++ b/src/main/resources/messages/messages_bg.yml @@ -45,7 +45,7 @@ unregistered: '&cУспешно от-регистриран!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fТвоята регистрация не е активирана, моля провери своя Имейл!' usage_unreg: '&cКоманда: /unregister парола' pwd_changed: '&cПаролата е променена!' @@ -87,8 +87,19 @@ email_send: '[AuthMe] Изпраен е имейл !' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cМоля добави своя имейл с : /email add имейл имейл' recovery_email: '&cЗабравихте своята парола? Моля използвай /email recovery <имейл>' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cYou need to type a captcha, please type: /captcha ' wrong_captcha: '&cГрешен код, използвай : /captcha THE_CAPTCHA' valid_captcha: '&cТвоя код е валиден!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_br.yml b/src/main/resources/messages/messages_br.yml index a6117b3be..c213f49cb 100644 --- a/src/main/resources/messages/messages_br.yml +++ b/src/main/resources/messages/messages_br.yml @@ -90,8 +90,19 @@ email_send_failure: '&cO e-mail não pôde ser enviado, reporte isso a um admini show_no_email: '&2Você atualmente não têm endereço de e-mail associado a esta conta.' add_email: '&3Por favor, adicione seu e-mail para a sua conta com o comando "/email add "' recovery_email: '&3Esqueceu sua senha? Por favor, use o comando "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Para iniciar sessão você tem que resolver um código captcha, utilize o comando "/captcha "' wrong_captcha: '&cCaptcha errado, por favor, escreva "/captcha THE_CAPTCHA" no chat!' valid_captcha: '&2Código Captcha resolvido corretamente!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_cz.yml b/src/main/resources/messages/messages_cz.yml index 8b653fb43..586a7376f 100644 --- a/src/main/resources/messages/messages_cz.yml +++ b/src/main/resources/messages/messages_cz.yml @@ -86,8 +86,19 @@ email_send_failure: 'Email nemohl být odeslán. Kontaktujte prosím admina.' show_no_email: '&2K tomuto účtu nemáte přidanou žádnou emailovou adresu.' add_email: '&cPřidej prosím svůj email pomocí : /email add TvůjEmail TvůjEmail' recovery_email: '&cZapomněl jsi heslo? Napiš: /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cPoužij: /captcha ' wrong_captcha: '&cŠpatné opsana Captcha, pouzij prosim: /captcha THE_CAPTCHA' valid_captcha: '&cZadaná captcha je v pořádku!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_de.yml b/src/main/resources/messages/messages_de.yml index 474c8237a..648a5153f 100644 --- a/src/main/resources/messages/messages_de.yml +++ b/src/main/resources/messages/messages_de.yml @@ -86,8 +86,19 @@ email_send_failure: 'Die E-Mail konnte nicht gesendet werden. Bitte kontaktiere show_no_email: '&2Du hast zur Zeit keine E-Mail-Adresse für deinen Account hinterlegt.' add_email: '&3Bitte hinterlege deine E-Mail-Adresse: /email add ' recovery_email: '&3Passwort vergessen? Nutze "/email recovery " für ein neues Passwort' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Um dich einzuloggen, tippe dieses Captcha so ein: /captcha ' wrong_captcha: '&cFalsches Captcha, bitte nutze: /captcha THE_CAPTCHA' valid_captcha: '&2Das Captcha ist korrekt!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index d1b147002..c71902341 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -86,8 +86,19 @@ email_send_failure: 'The email could not be sent. Please contact an administrato show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&3Please add your email to your account with the command: /email add ' recovery_email: '&3Forgot your password? Please use the command: /email recovery ' +email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3To login you have to solve a captcha code, please use the command: /captcha ' wrong_captcha: '&cWrong captcha, please type "/captcha THE_CAPTCHA" into the chat!' valid_captcha: '&2Captcha code solved correctly!' + +# Time units +second: 'second' +seconds: 'seconds' +minute: 'minute' +minutes: 'minutes' +hour: 'hour' +hours: 'hours' +day: 'day' +days: 'days' diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml index e0c0c96dd..ac7415718 100644 --- a/src/main/resources/messages/messages_es.yml +++ b/src/main/resources/messages/messages_es.yml @@ -89,8 +89,19 @@ email_send_failure: 'No se ha podido enviar el correo electrónico. Por favor, c show_no_email: '&2No tienes ningun E-Mail asociado en esta cuenta.' add_email: '&cPor favor agrega tu e-mail con: /email add tuEmail confirmarEmail' recovery_email: '&c¿Olvidaste tu contraseña? Por favor usa /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cUso: /captcha ' wrong_captcha: '&cCaptcha incorrecto, por favor usa: /captcha THE_CAPTCHA' valid_captcha: '&c¡ Captcha ingresado correctamente !' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_eu.yml b/src/main/resources/messages/messages_eu.yml index 53b0704d6..05473e68a 100644 --- a/src/main/resources/messages/messages_eu.yml +++ b/src/main/resources/messages/messages_eu.yml @@ -45,7 +45,7 @@ unregistered: '&cZure erregistroa ezabatu duzu!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fZure kontua aktibatu gabe dago, konfirmatu zure emaila!' usage_unreg: '&cErabili: /unregister password' pwd_changed: '&cPasahitza aldatu duzu!' @@ -87,8 +87,19 @@ email_send: '[AuthMe] Berreskuratze emaila bidalita !' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cMesedez gehitu zure emaila : /email add yourEmail confirmEmail' recovery_email: '&cPasahitza ahaztu duzu? Erabili /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha -# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command "/captcha "' +# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command: /captcha ' # TODO wrong_captcha: '&cWrong captcha, please type "/captcha THE_CAPTCHA" into the chat!' # TODO valid_captcha: '&2Captcha code solved correctly!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_fi.yml b/src/main/resources/messages/messages_fi.yml index bf359e8c9..a48ac74db 100644 --- a/src/main/resources/messages/messages_fi.yml +++ b/src/main/resources/messages/messages_fi.yml @@ -45,7 +45,7 @@ unregistered: '&cPelaajatili poistettu onnistuneesti!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fKäyttäjäsi ei ole vahvistettu!' usage_unreg: '&cKäyttötapa: /unregister password' pwd_changed: '&cSalasana vaihdettu!!' @@ -87,8 +87,19 @@ email_send: '[AuthMe] Palautus sähköposti lähetetty!' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cLisää sähköpostisi: /email add sähköpostisi sähköpostisiUudelleen' recovery_email: '&cUnohtuiko salasana? Käytä komentoa: /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cKäyttötapa: /captcha ' wrong_captcha: '&cVäärä varmistus, käytä : /captcha THE_CAPTCHA' valid_captcha: '&cSinun varmistus onnistui.!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_fr.yml b/src/main/resources/messages/messages_fr.yml index 1bd884568..dd01ccc6f 100644 --- a/src/main/resources/messages/messages_fr.yml +++ b/src/main/resources/messages/messages_fr.yml @@ -91,8 +91,19 @@ email_send_failure: '&cL''email n''a pas pu être envoyé. Veuillez contacter un show_no_email: 'Vous n''avez aucune adresse email enregistré sur votre compte.' add_email: '&cMerci d''ajouter votre email : /email add ' recovery_email: '&cVous avez oublié votre Mot de Passe? Utilisez /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cTrop de tentatives de connexion échouées, utilisez: /captcha ' wrong_captcha: '&cCaptcha incorrect, écrivez de nouveau : /captcha THE_CAPTCHA' valid_captcha: '&aCaptché validé! Veuillez maintenant vous connecter.' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_gl.yml b/src/main/resources/messages/messages_gl.yml index 2739a1a8f..1c0570306 100644 --- a/src/main/resources/messages/messages_gl.yml +++ b/src/main/resources/messages/messages_gl.yml @@ -45,7 +45,7 @@ unregistered: '&cFeito! Xa non estás rexistrado!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fA túa conta aínda non está activada, comproba a túa bandexa de correo!!' usage_unreg: '&cUso: /unregister ' pwd_changed: '&cCambiouse o contrasinal!' @@ -87,8 +87,19 @@ email_send: '[AuthMe] Enviouse o correo de confirmación!' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cPor favor, engade o teu correo electrónico con: /email add ' recovery_email: '&cOlvidaches o contrasinal? Por favor, usa /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cNecesitas escribir un captcha, por favor escribe: /captcha ' wrong_captcha: '&cCaptcha equivocado, por favor usa: /captcha THE_CAPTCHA' valid_captcha: '&cO teu captcha é válido !' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_hu.yml b/src/main/resources/messages/messages_hu.yml index f5667eb89..dc62f8c18 100644 --- a/src/main/resources/messages/messages_hu.yml +++ b/src/main/resources/messages/messages_hu.yml @@ -86,8 +86,19 @@ email_already_used: '&4Ez az email cím már használatban van!' show_no_email: '&2Ehhez a felhasználóhoz jelenleg még nincs email hozzárendelve.' add_email: '&3Kérlek rendeld hozzá a felhasználódhoz az email címedet "/email add "' recovery_email: '&3Ha elfelejtetted a jelszavad, használd az: "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3A bejelentkezéshez CAPTCHA szükséges, kérlek használd a következő parancsot "/captcha "' wrong_captcha: '&cHibás CAPTCHA, kérlek írd be a következő parancsot: "/captcha THE_CAPTCHA"!' valid_captcha: '&2CAPTCHA sikeresen feloldva!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_id.yml b/src/main/resources/messages/messages_id.yml index b4fde4abb..90db87bd8 100644 --- a/src/main/resources/messages/messages_id.yml +++ b/src/main/resources/messages/messages_id.yml @@ -45,7 +45,7 @@ unregistered: '&cUnregister berhasil!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&cAkunmu belum diaktifkan, silahkan periksa email kamu!' # TODO usage_unreg: '&cUsage: /unregister ' pwd_changed: '&2Berhasil mengubah password!' @@ -87,8 +87,19 @@ email_exists: '&cEmail pemulihan sudah dikirim! kamu bisa membatalkan dan mengir # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&3Silahkan tambahkan email ke akunmu menggunakan command "/email add "' recovery_email: '&3Lupa password? silahkan gunakan command "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Kamu harus menyelesaikan kode captcha untuk login, silahkan gunakan command "/captcha "' wrong_captcha: '&cCaptcha salah, gunakan command "/captcha THE_CAPTCHA" pada chat!' valid_captcha: '&2Kode captcha terselesaikan!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_it.yml b/src/main/resources/messages/messages_it.yml index cdf6fed82..ede276906 100644 --- a/src/main/resources/messages/messages_it.yml +++ b/src/main/resources/messages/messages_it.yml @@ -88,8 +88,19 @@ email_send_failure: 'Non è stato possibile inviare l''email contenente la tua n show_no_email: '&2Al momento non hai nessun indirizzo email associato al tuo account.' add_email: '&3Per poter recuperare la password in futuro, aggiungi un indirizzo email al tuo account con il comando: /email add ' recovery_email: '&3Hai dimenticato la tua password? Puoi recuperarla eseguendo il comando: /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Per poterti autenticare devi risolvere un captcha, per favore scrivi: /captcha ' wrong_captcha: '&cCaptcha sbagliato, per favore riprova scrivendo: "/captcha THE_CAPTCHA" in chat!' valid_captcha: '&2Il captcha inserito è valido!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_ko.yml b/src/main/resources/messages/messages_ko.yml index db7bc8aa5..a65d93526 100644 --- a/src/main/resources/messages/messages_ko.yml +++ b/src/main/resources/messages/messages_ko.yml @@ -49,7 +49,7 @@ unregistered: '&c성공적으로 탈퇴했습니다!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&f당신의 계정은 아직 활성화되어있지 않습니다, 당신의 이메일을 확인해보세요!' usage_unreg: '&c사용법: /unregister 비밀번호' pwd_changed: '&c비밀번호를 변경했습니다!' @@ -91,8 +91,19 @@ email_exists: '[AuthMe] 당신의 계정에 이미 이메일이 존재합니다. # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&c당신의 이메일을 추가해주세요 : /email add 당신의이메일 이메일재입력' recovery_email: '&c비밀번호를 잊어버리셨다고요? /email recovery <당신의이메일>을 사용하세요' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&c보안문자 입력이 필요합니다, 입력해주세요: /captcha ' wrong_captcha: '&c잘못된 보안문자, 사용해주세요 : /captcha THE_CAPTCHA' valid_captcha: '&c당신의 보안문자는 적합합니다!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_lt.yml b/src/main/resources/messages/messages_lt.yml index a2bcbe257..d75dec4a1 100644 --- a/src/main/resources/messages/messages_lt.yml +++ b/src/main/resources/messages/messages_lt.yml @@ -45,7 +45,7 @@ unregistered: '&aSekmingai issiregistravote!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&aJusu vartotojas nera patvirtintas, patikrinkite el.pasta.' usage_unreg: '&ePanaikinti registracija: "/unregister slaptazodis"' pwd_changed: '&aSlaptazodis pakeistas' @@ -87,8 +87,19 @@ same_nick: '&cKazkas situo vardu jau zaidzia.' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&ePrasau pridekite savo el.pasta : /email add Email confirmEmail' recovery_email: '&cPamirsote slaptazodi? Rasykite: /email recovery el.pastas' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cPanaudojimas: /captcha ' wrong_captcha: '&cNeteisinga Captcha, naudokite : /captcha THE_CAPTCHA' valid_captcha: '&cJusu captcha Teisinga!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_nl.yml b/src/main/resources/messages/messages_nl.yml index 2ee68f951..630fadd6e 100644 --- a/src/main/resources/messages/messages_nl.yml +++ b/src/main/resources/messages/messages_nl.yml @@ -86,8 +86,19 @@ email_send_failure: 'De E-mail kon niet verzonden worden. Neem contact op met ee show_no_email: '&2Je hebt nog geen E-mailadres toegevoegd aan dit account.' add_email: '&3Voeg jouw E-mailadres alsjeblieft toe met: /email add ' recovery_email: '&3Wachtwoord vergeten? Gebruik alsjeblieft het commando: /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Om in te loggen moet je een captcha-code oplossen, gebruik het commando: /captcha ' wrong_captcha: '&cVerkeerde captcha-code, typ alsjeblieft "/captcha THE_CAPTCHA" in de chat!' valid_captcha: '&2De captcha-code is geldig!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_pl.yml b/src/main/resources/messages/messages_pl.yml index 3f9e37ae9..549efb9e1 100644 --- a/src/main/resources/messages/messages_pl.yml +++ b/src/main/resources/messages/messages_pl.yml @@ -87,8 +87,19 @@ email_send_failure: 'Nie mozna wyslac emaila. Skontaktuj sie z administracja.' show_no_email: '&2Nie posiadasz adresu email przypisanego do tego konta.' add_email: '&cProsze dodac swoj email: /email add twojEmail powtorzEmail' recovery_email: '&cZapomniales hasla? Prosze uzyj komendy /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cWpisz: /captcha ' wrong_captcha: '&cZly kod, prosze wpisac: /captcha THE_CAPTCHA' valid_captcha: '&cTwoj kod jest nieprawidlowy!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_pt.yml b/src/main/resources/messages/messages_pt.yml index 7254f8bbf..fef35f74f 100644 --- a/src/main/resources/messages/messages_pt.yml +++ b/src/main/resources/messages/messages_pt.yml @@ -45,7 +45,7 @@ unregistered: '&cRegisto eliminado com sucesso!' # TODO accounts_owned_other: 'The player %name has %count accounts:' two_factor_create: '&2O seu código secreto é o %code. Você pode verificá-lo a partir daqui %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fA sua conta não foi ainda activada, verifique o seu email onde irá receber indicações para activação de conta. ' usage_unreg: '&cUse: /unregister password' pwd_changed: '&cPassword alterada!' @@ -87,8 +87,19 @@ email_already_used: '&4O endereço de e-mail já está sendo usado' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cPor favor adicione o seu email com : /email add seuEmail confirmarSeuEmail' recovery_email: '&cPerdeu a sua password? Para a recuperar escreva /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&cPrecisa digitar um captcha, escreva: /captcha ' wrong_captcha: '&cCaptcha errado, por favor escreva: /captcha THE_CAPTCHA' valid_captcha: '&cO seu captcha é válido!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml index d1726d69b..703b93f59 100644 --- a/src/main/resources/messages/messages_ro.yml +++ b/src/main/resources/messages/messages_ro.yml @@ -86,8 +86,19 @@ email_already_used: '&4Email-ul a fost deja folosit' show_no_email: '&2Nu ai nici-o adresa de email asociat cu acest cont.' add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "' recovery_email: '&3Ti-ai uitat parola? Te rugam foloseste comanda "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha THE_CAPTCHA"!' valid_captcha: '&2Cod-ul captcha a fost scris corect!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_ru.yml b/src/main/resources/messages/messages_ru.yml index 873b63979..11f55835e 100644 --- a/src/main/resources/messages/messages_ru.yml +++ b/src/main/resources/messages/messages_ru.yml @@ -86,8 +86,19 @@ email_send_failure: 'Письмо не може быть отправлено. show_no_email: '&2В данный момент к вашему аккаунте не привязана электронная почта.' add_email: '&cДобавьте свой email: &e/email add <Ваш Email> <Ваш Email>' recovery_email: '&cЗабыли пароль? Используйте &e/email recovery <Ваш Email>' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Каптча usage_captcha: '&cВы должны ввести код, используйте: &e/captcha ' wrong_captcha: '&cНеверный код, используйте: &e/captcha THE_CAPTCHA' valid_captcha: '&2Вы успешно ввели код!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_sk.yml b/src/main/resources/messages/messages_sk.yml index 5eb97d929..b49f8cf5c 100644 --- a/src/main/resources/messages/messages_sk.yml +++ b/src/main/resources/messages/messages_sk.yml @@ -49,7 +49,7 @@ unregistered: '&cUcet bol vymazany!' # TODO accounts_owned_other: 'The player %name has %count accounts:' # TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&fUcet nie je aktivny. Prezri si svoj e-mail!' usage_unreg: '&cPríkaz: /unregister heslo' pwd_changed: '&cHeslo zmenené!' @@ -91,8 +91,19 @@ same_nick: '&fHrác s tymto nickom uz hrá!' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&cPridaj svoj e-mail príkazom "/email add email zopakujEmail"' recovery_email: '&cZabudol si heslo? Pouzi príkaz /email recovery ' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha -# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command "/captcha "' +# TODO usage_captcha: '&3To login you have to solve a captcha code, please use the command: /captcha ' # TODO wrong_captcha: '&cWrong captcha, please type "/captcha THE_CAPTCHA" into the chat!' # TODO valid_captcha: '&2Captcha code solved correctly!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_tr.yml b/src/main/resources/messages/messages_tr.yml index 480e0e5b2..a3ba1f262 100644 --- a/src/main/resources/messages/messages_tr.yml +++ b/src/main/resources/messages/messages_tr.yml @@ -44,7 +44,7 @@ unregistered: '&cKayit basariyla kaldirildi!' # TODO accounts_owned_other: 'The player %name has %count accounts:' two_factor_create: '&2Gizli kodunuz %code. Buradan test edebilirsin, %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&cHeabiniz henuz aktif edilmemis, e-postanizi kontrol edin!' usage_unreg: '&cKullanim: /unregister ' pwd_changed: '&2Sifre basariyla degistirildi!' @@ -86,8 +86,19 @@ email_already_used: '&4Eposta adresi zaten kullaniliyor.' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&3Lutfen hesabinize eposta adresinizi komut ile ekleyin "/email add "' recovery_email: '&3Sifreni mi unuttun ? Komut kullanarak ogrenebilirsin "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Giris yapmak icin guvenlik kodunu komut yazarak girin "/captcha "' wrong_captcha: '&cYanlis guvenlik kodu, kullanim sekli "/captcha THE_CAPTCHA" sohbete yazin!' valid_captcha: '&2Guvenlik kodu dogrulandi!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_uk.yml b/src/main/resources/messages/messages_uk.yml index d1d53187f..35dbbffee 100644 --- a/src/main/resources/messages/messages_uk.yml +++ b/src/main/resources/messages/messages_uk.yml @@ -44,7 +44,7 @@ accounts_owned_self: 'Кількість ваших твінк‒акаунті accounts_owned_other: 'Кількість твінк‒акаунтів гравця %name: %count' two_factor_create: '&2Ваш секретний код — %code %nl%&2Можете зкопіювати його за цим посиланням — %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&cВаш акаунт ще не активовано. Будь ласка, провірте свою електронну пошту!' usage_unreg: '&cСинтаксис: /unregister <пароль>' pwd_changed: '&2Пароль успішно змінено!' @@ -86,8 +86,19 @@ email_already_used: '&4До цієї електронної пошти прив # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&3Не забудьте прив’язати електронну пошту до свого акаунта, за допомогою команди "/email add "' recovery_email: 'Забули пароль? Можете скористатись командою &9/email recovery &f<&9ваш e-mail&f>' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3Для продовження доведеться ввести капчу — "/captcha "' wrong_captcha: '&cНевірно введена капча! Спробуйте ще раз — "/captcha THE_CAPTCHA"' valid_captcha: '&2Капчу прийнято.' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_vn.yml b/src/main/resources/messages/messages_vn.yml index 4cb86ae86..7f68be063 100644 --- a/src/main/resources/messages/messages_vn.yml +++ b/src/main/resources/messages/messages_vn.yml @@ -86,8 +86,19 @@ email_send_failure: 'Không thể gửi thư. Vui lòng liên hệ với ban qu show_no_email: '&2Hiện tại bạn chưa liên kết bất kỳ email nào với tài khoản này.' add_email: '&eVui lòng thêm email của bạn với lệnh "/email add "' recovery_email: '&aBạn quên mật khẩu? Vui lòng gõ lệnh "/email recovery "' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&eĐể đăng nhập vui lòng hãy gõ mã Captcha, gõ lệnh "/captcha "' wrong_captcha: '&cSai mã captcha, Vui lòng nhấn "/captcha THE_CAPTCHA" trong kênh chát!' valid_captcha: '&2Mã captcha đã được xác nhận!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_zhcn.yml b/src/main/resources/messages/messages_zhcn.yml index e6c5e755f..63922334d 100644 --- a/src/main/resources/messages/messages_zhcn.yml +++ b/src/main/resources/messages/messages_zhcn.yml @@ -87,8 +87,19 @@ email_send_failure: '邮件发送失败,请联系管理员' show_no_email: '&2您当前并没有任何邮箱与该账号绑定' add_email: '&8[&6玩家系统&8] &c请输入“/email add <你的邮箱> <再输入一次以确认>”以把你的邮箱添加到此帐号' recovery_email: '&8[&6玩家系统&8] &c忘了你的密码?请输入:“/email recovery <你的邮箱>”' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&8[&6玩家系统&8] &c正确用法:/captcha ' wrong_captcha: '&8[&6玩家系统&8] &c错误的验证码,请输入:“/captcha THE_CAPTCHA”' valid_captcha: '&8[&6玩家系统&8] &c你的验证码是有效的!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_zhhk.yml b/src/main/resources/messages/messages_zhhk.yml index a07d52490..896003d4f 100644 --- a/src/main/resources/messages/messages_zhhk.yml +++ b/src/main/resources/messages/messages_zhhk.yml @@ -49,7 +49,7 @@ unregistered: '&8[&6用戶系統&8] &c你已成功刪除會員註冊記錄。' # TODO accounts_owned_other: 'The player %name has %count accounts:' two_factor_create: '&8[&6用戶系統 - 兩步驗證碼&8] &b你的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&8[&6用戶系統&8] &f你的帳戶還沒有經過電郵驗證 !' usage_unreg: '&8[&6用戶系統&8] &f用法: 《 /unregister <密碼> 》' pwd_changed: '&8[&6用戶系統&8] &c你成功更換了你的密碼 !' @@ -91,8 +91,19 @@ email_already_used: '&8[&6用戶系統&8] &4這個電郵地址已被使用。' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&8[&6用戶系統&8] &b請為你的帳戶立即添加電郵地址: 《 /email add <電郵地址> <重覆電郵地址> 》' recovery_email: '&8[&6用戶系統&8] &b忘記密碼?請使用 /email recovery <電郵地址> 來更新密碼。' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&8[&6用戶系統&8] &f用法: 《 /captcha 》' wrong_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效,請使用 《 /captcha THE_CAPTCHA 》 再次輸入。' valid_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效 !' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_zhmc.yml b/src/main/resources/messages/messages_zhmc.yml index 1d9876ad8..92f9113ea 100644 --- a/src/main/resources/messages/messages_zhmc.yml +++ b/src/main/resources/messages/messages_zhmc.yml @@ -86,8 +86,19 @@ email_already_used: '&4此電子郵件地址已被使用' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&3請使用命令: /email add [你的電郵地址] [重覆確認你的電郵地址] 將您的電子郵件添加到您的帳戶"' recovery_email: '&3忘記密碼了嗎? 請使用命令: "/email recovery [你的電郵地址]"' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&3T要登錄您必須使用captcha驗證碼,請使用命令: "/captcha "' wrong_captcha: '&c驗證碼錯誤!請按T在聊天中輸入 "/captcha THE_CAPTCHA"' valid_captcha: '&2驗證碼正確!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days' diff --git a/src/main/resources/messages/messages_zhtw.yml b/src/main/resources/messages/messages_zhtw.yml index b5dc97cf2..b2cff0384 100644 --- a/src/main/resources/messages/messages_zhtw.yml +++ b/src/main/resources/messages/messages_zhtw.yml @@ -49,7 +49,7 @@ unregistered: '&b【AuthMe】&6你已經成功取消註冊。' # TODO accounts_owned_other: 'The player %name has %count accounts:' two_factor_create: '&b【AuthMe - 兩步驗證碼】&b你的登入金鑰為&9「%c%code&9」&b,掃描連結為:&c %url' # TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one' vb_nonActiv: '&b【AuthMe】&6你的帳號還沒有經過驗證! 檢查看看你的電子信箱 (Email) 吧!' usage_unreg: '&b【AuthMe】&6用法: &c"/unregister <密碼>"' pwd_changed: '&b【AuthMe】&6密碼變更成功!' @@ -91,8 +91,19 @@ email_already_used: '&b【AuthMe】&4這個電郵地址已被使用。' # TODO show_no_email: '&2You currently don''t have email address associated with this account.' add_email: '&b【AuthMe】&6請使用 &c"/email add <你的Email> <再次輸入你的Email>" &6來添加 Email' recovery_email: '&b【AuthMe】&6忘記密碼了嗎? 使用 &c"/email recovery <你的Email>"' +# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.' # Captcha usage_captcha: '&b【AuthMe】&6請用 &c"/captcha " &6來輸入你的驗證碼' wrong_captcha: '&b【AuthMe】&6錯誤的驗證碼,請使用 《 /captcha THE_CAPTCHA 》 再試一次吧。' valid_captcha: '&b【AuthMe】&6驗證碼無效!' + +# Time units +# TODO second: 'second' +# TODO seconds: 'seconds' +# TODO minute: 'minute' +# TODO minutes: 'minutes' +# TODO hour: 'hour' +# TODO hours: 'hours' +# TODO day: 'day' +# TODO days: 'days'