Commit ee512a15 authored by Jose Blaya's avatar Jose Blaya
Browse files

Merge branch 'release/2.7.3' into develop

parents b8f5527c 92d5707a
......@@ -14,6 +14,7 @@ before_script:
#- bundle exec fastlane run ensure_git_status_clean
- echo "$PIA_STAGING_ENDPOINT" >"Resources/staging.endpoint"
- echo "$PIA_CUSTOM_SERVERS" >"Resources/custom.servers"
- echo "$PIA_FIREBASE_PLIST" >"Resources/GoogleService-Info.plist"
stages:
- test
......
......@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.7.0</string>
<string>2.7.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
......
......@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.7.0</string>
<string>2.7.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
......
This diff is collapsed.
......@@ -31,14 +31,6 @@ class AccountViewController: AutolayoutViewController {
@IBOutlet private weak var textUsername: BorderedTextField!
@IBOutlet private weak var labelPassword: UILabel!
@IBOutlet private weak var textPassword: BorderedTextField!
@IBOutlet private weak var buttonEye: UIButton!
@IBOutlet private weak var labelFooterEye: UILabel!
@IBOutlet private weak var labelFooterOther: UILabel!
@IBOutlet weak var labelExpiryInformation: UILabel!
......@@ -78,10 +70,7 @@ class AccountViewController: AutolayoutViewController {
labelEmail.text = L10n.Account.Email.caption
textEmail.placeholder = L10n.Account.Email.placeholder
labelUsername.text = L10n.Account.Username.caption
labelPassword.text = L10n.Account.Password.caption
buttonEye.setImage(Asset.iconEye.image, for: .normal)
itemUpdate.title = L10n.Account.Save.item
labelFooterEye.text = L10n.Account.Eye.footer
labelFooterOther.text = L10n.Account.Other.footer
labelRestoreTitle.text = L10n.Account.Restore.title
labelRestoreInfo.text = L10n.Account.Restore.description
......@@ -90,9 +79,7 @@ class AccountViewController: AutolayoutViewController {
viewSafe.layoutMargins = .zero
textEmail.isEditable = true
textUsername.isEditable = false
textPassword.isEditable = false
canSaveAccount = false
updateEyeAccessibilityToPasswordVisibility(false)
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(redisplayAccount), name: .PIAAccountDidRefresh, object: nil)
......@@ -130,76 +117,71 @@ class AccountViewController: AutolayoutViewController {
// MARK: Actions
@IBAction private func saveChanges(_ sender: Any?) {
textEmail.resignFirstResponder()
guard canSaveAccount else {
return
}
SensitiveOperation.perform(withReason: L10n.Account.Save.prompt) {
guard let email = self.textEmail.text else {
return
}
log.debug("Account: Modifying account email...")
let request = UpdateAccountRequest(email: email)
let hud = HUD()
guard let email = self.textEmail.text else {
return
}
let alert = Macros.alert(L10n.Account.Update.Email.Require.Password.title,
L10n.Account.Update.Email.Require.Password.message)
alert.addCancelAction(L10n.Global.cancel)
let action = UIAlertAction(title: L10n.Account.Update.Email.Require.Password.button,
style: .default) { [weak self] (alertAction) in
Client.providers.accountProvider.update(with: request) { (info, error) in
hud.hide()
guard let _ = info else {
if let error = error {
log.error("Account: Failed to modify account email (error: \(error))")
} else {
log.error("Account: Failed to modify account email")
if let weakSelf = self {
if let textField = alert.textFields?.first,
let password = textField.text {
log.debug("Account: Modifying account email...")
let request = UpdateAccountRequest(email: email)
let hud = HUD()
Client.providers.accountProvider.update(with: request,
andPassword: password) { (info, error) in
hud.hide()
guard let _ = info else {
if let error = error {
log.error("Account: Failed to modify account email (error: \(error))")
} else {
log.error("Account: Failed to modify account email")
}
weakSelf.textEmail.text = ""
let alert = Macros.alert(L10n.Global.error, L10n.Account.Error.unauthorized)
alert.addCancelAction(L10n.Global.close)
self?.present(alert, animated: true, completion: nil)
return
}
log.debug("Account: Email successfully modified")
let alert = Macros.alert(nil, L10n.Account.Save.success)
alert.addCancelAction(L10n.Global.ok)
weakSelf.present(alert, animated: true, completion: nil)
weakSelf.textEmail.text = email
weakSelf.textEmail.endEditing(true)
weakSelf.canSaveAccount = false
}
self.textEmail.text = ""
let alert = Macros.alert(L10n.Global.error, error?.localizedDescription)
alert.addCancelAction(L10n.Global.close)
self.present(alert, animated: true, completion: nil)
return
}
log.debug("Account: Email successfully modified")
let alert = Macros.alert(nil, L10n.Account.Save.success)
alert.addCancelAction(L10n.Global.ok)
self.present(alert, animated: true, completion: nil)
self.textEmail.text = email
self.textEmail.endEditing(true)
self.canSaveAccount = false
}
}
}
@IBAction private func togglePasswordVisibility(_ sender: Any?) {
// conceal
if !textPassword.isSecureTextEntry {
textPassword.isSecureTextEntry = true
updateEyeAccessibilityToPasswordVisibility(false)
}
// reveal
else {
SensitiveOperation.perform(withReason: L10n.Account.Reveal.prompt) {
self.textPassword.isSecureTextEntry = false
self.updateEyeAccessibilityToPasswordVisibility(true)
}
}
}
private func updateEyeAccessibilityToPasswordVisibility(_ passwordVisibility: Bool) {
buttonEye.accessibilityLabel = L10n.Account.Accessibility.eye
let hint: String
if passwordVisibility {
hint = L10n.Account.Accessibility.Eye.Hint.conceal
} else {
hint = L10n.Account.Accessibility.Eye.Hint.reveal
alert.addTextField { (textField) in
textField.isSecureTextEntry = true
}
buttonEye.accessibilityHint = hint
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
@IBAction private func renewSubscriptionWithUncreditedPurchase(_ sender: Any?) {
......@@ -269,8 +251,7 @@ class AccountViewController: AutolayoutViewController {
textEmail.endEditing(true)
textEmail.text = currentUser?.info?.email
textEmail.isEnabled = !(currentUser?.info?.isExpired ?? true)
textUsername.text = currentUser?.credentials.username
textPassword.text = currentUser?.credentials.password
textUsername.text = Client.providers.accountProvider.publicUsername ?? ""
if let userInfo = currentUser?.info {
if userInfo.isExpired {
......@@ -303,14 +284,13 @@ class AccountViewController: AutolayoutViewController {
override func viewShouldRestyle() {
super.viewShouldRestyle()
for label in [labelEmail!, labelUsername!, labelPassword!] {
for label in [labelEmail!, labelUsername!] {
Theme.current.applyLabel(label, appearance: .dark)
}
Theme.current.applyInput(textEmail)
Theme.current.applyInput(textUsername)
Theme.current.applyInput(textPassword)
Theme.current.applyDivider(viewSeparator)
for label in [labelFooterEye!, labelFooterOther!, labelExpiryInformation!] {
for label in [labelFooterOther!, labelExpiryInformation!] {
Theme.current.applySmallInfo(label, appearance: .dark)
}
Theme.current.applyBody2(labelRestoreTitle, appearance: .dark)
......
......@@ -32,7 +32,7 @@ class AppPreferences {
static let shared = AppPreferences()
private static let currentVersion = "3.0"
private static let currentVersion = "4.0"
private let defaults: UserDefaults
......@@ -118,12 +118,30 @@ class AppPreferences {
])
}
private func migrateAPItoV2() {
// Migrate users from v1 to v2
log.debug("Migration to api v2")
//For v1 we stored the username in the plain database. We move the value to the keychain database.
//After refresh the account, the token will be generated
if let oldUsername = defaults.string(forKey: "LoggedUsername"),
let _ = try? PIALibrary.Keychain(team: AppConstants.teamId,
group: AppConstants.appGroup).password(for: oldUsername) {
//User is loggedIn
try? PIALibrary.Keychain().set(username: oldUsername)
try? PIALibrary.Keychain().set(publicUsername: oldUsername)
defaults.removeObject(forKey: "LoggedUsername")
defaults.synchronize()
}
}
func migrate() {
let oldVersion = defaults.string(forKey: Entries.version)
defaults.set(AppPreferences.currentVersion, forKey: Entries.version)
guard (oldVersion == nil) else {
// migration to 3.0
if oldVersion != "4.0" {
migrateAPItoV2()
}
return
}
......@@ -169,6 +187,9 @@ class AppPreferences {
// NSString *subscriptionPlan = [oldDefaults objectForKey:@"SubscriptionPlan"];
oldDefaults.removeObject(forKey: "SubscriptionExpirationDate")
oldDefaults.removeObject(forKey: "SubscriptionPlan")
migrateAPItoV2()
}
func reset() {
......
......@@ -13,6 +13,7 @@ import SwiftyBeaver
import iRate
#if PIA_DEV
import HockeySDK
import Firebase
#endif
class Bootstrapper {
......@@ -127,6 +128,13 @@ class Bootstrapper {
hockey.isMetricsManagerDisabled = true
hockey.configure(withIdentifier: AppConstants.hockeyAppId)
hockey.start()
if let path = Bundle.main.url(forResource: "GoogleService-Info", withExtension: "plist"),
let plist = NSDictionary(contentsOf: path) as? [String: Any],
plist.count > 0 {
FirebaseApp.configure()
}
#endif
// Notifications
......
......@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.7.0</string>
<string>2.7.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSpokenName</key>
......@@ -41,10 +41,10 @@
<string></string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>Authenticate to reveal</string>
<key>NSCameraUsageDescription</key>
<string>We need camera access to scan a code from an gift card</string>
<key>NSFaceIDUsageDescription</key>
<string>Authenticate to reveal</string>
<key>UIAppFonts</key>
<array>
<string>Roboto-Light.ttf</string>
......
......@@ -124,8 +124,8 @@ class MenuViewController: AutolayoutViewController {
assert(Client.providers.accountProvider.isLoggedIn, "Menu visible while not logged in")
currentUser = Client.providers.accountProvider.currentUser
labelUsername.text = currentUser?.credentials.username
labelUsername.accessibilityLabel = L10n.Menu.Accessibility.loggedAs(currentUser?.credentials.username ?? "")
labelUsername.text = Client.providers.accountProvider.publicUsername ?? ""
labelUsername.accessibilityLabel = L10n.Menu.Accessibility.loggedAs(Client.providers.accountProvider.publicUsername ?? "")
}
override func didRefreshOrientationConstraints() {
......
......@@ -44,6 +44,10 @@ internal enum L10n {
/// Email address
internal static let placeholder = L10n.tr("Localizable", "account.email.placeholder")
}
internal enum Error {
/// Your username or password is incorrect.
internal static let unauthorized = L10n.tr("Localizable", "account.error.unauthorized")
}
internal enum ExpiryDate {
/// Your plan has expired.
internal static let expired = L10n.tr("Localizable", "account.expiry_date.expired")
......@@ -83,13 +87,27 @@ internal enum L10n {
internal static let prompt = L10n.tr("Localizable", "account.reveal.prompt")
}
internal enum Save {
/// Update
/// Update email
internal static let item = L10n.tr("Localizable", "account.save.item")
/// Authenticate to save changes
internal static let prompt = L10n.tr("Localizable", "account.save.prompt")
/// Your email address has been saved.
internal static let success = L10n.tr("Localizable", "account.save.success")
}
internal enum Update {
internal enum Email {
internal enum Require {
internal enum Password {
/// Submit
internal static let button = L10n.tr("Localizable", "account.update.email.require.password.button")
/// For security reasons we require your PIA password to perform a change in your account. Please input your PIA password to proceed.
internal static let message = L10n.tr("Localizable", "account.update.email.require.password.message")
/// PIA Password Required
internal static let title = L10n.tr("Localizable", "account.update.email.require.password.title")
}
}
}
}
internal enum Username {
/// Username
internal static let caption = L10n.tr("Localizable", "account.username.caption")
......@@ -377,7 +395,7 @@ internal enum L10n {
internal static let title = L10n.tr("Localizable", "settings.dns.alert.clear.title")
}
internal enum Create {
/// Be warned: Using a non-PIA DNS could compromise your privacy.
/// Using non PIA DNS could expose your DNS traffic to third parties and compromise your privacy.
internal static let message = L10n.tr("Localizable", "settings.dns.alert.create.message")
}
}
......@@ -387,13 +405,13 @@ internal enum L10n {
}
internal enum Validation {
internal enum Primary {
/// Primary DNS is not valid
/// Primary DNS is not valid.
internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.primary.invalid")
/// Primary DNS is mandatory
/// Primary DNS is mandatory.
internal static let mandatory = L10n.tr("Localizable", "settings.dns.validation.primary.mandatory")
}
internal enum Secondary {
/// Secondary DNS is not valid
/// Secondary DNS is not valid.
internal static let invalid = L10n.tr("Localizable", "settings.dns.validation.secondary.invalid")
}
}
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "اضغط لإظهار كلمة المرور";
"account.email.caption" = "البريد الإلكتروني";
"account.email.placeholder" = "البريد الإلكتروني";
"account.error.unauthorized" = "اسم المستخدم أو كلمة المرور غير صحيحة.";
"account.expiry_date.expired" = "لقد انتهت صلاحية خطتك.";
"account.expiry_date.information" = "ستنتهي صلاحية خطتك في %@.";
"account.eye.footer" = "اضغط على رمز العين للكشف عن كلمة المرور أو إخفائها.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "استرداد الشراء";
"account.restore.title" = "استرداد الشراء غير المقيد في الحساب";
"account.reveal.prompt" = "مصادقة للإظهار";
"account.save.item" = "تحديث";
"account.save.item" = "تحديث البريد الإلكتروني";
"account.save.prompt" = "مصادقة لحفظ التغييرات";
"account.save.success" = "تم حفظ عنوان بريدك الإلكتروني.";
"account.update.email.require.password.button" = "إرسال";
"account.update.email.require.password.message" = "لأسباب أمنية، نطلب كلمة مرور PIA الخاصة بك عند إجراء تغييرات على حسابك. يرجى إدخال كلمة مرور PIA للمتابعة.";
"account.update.email.require.password.title" = "كلمة مرور PIA مطلوبة";
"account.username.caption" = "اسم المستخدم";
"content_blocker.body.footer" = "يرجى الملاحظة: يعمل حظر المحتوى دون الحاجة للاتصال بشبكة VPN، ولكنه لن يعمل إلا على متصفح Safari.";
"content_blocker.body.subtitle" = "لتفعيل استخدام حظر المحتوى على متصفح Safari، يرجى الذهاب الى الإعدادات > Safari وتفعيل PIA VPN تحت General touch Content Blockers";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "Tryk for at vise kodeord";
"account.email.caption" = "E-mail";
"account.email.placeholder" = "E-mailadresse";
"account.error.unauthorized" = "Dit brugernavn eller kodeord er forkert.";
"account.expiry_date.expired" = "Din plan er udløbet.";
"account.expiry_date.information" = "Din plan vil udløbe om %@.";
"account.eye.footer" = "Tryk på øjenikonet for at afsløre eller skjule dit kodeord.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "Gendan køb";
"account.restore.title" = "Gendan ukrediteret køb";
"account.reveal.prompt" = "Autentificer for at afsløre";
"account.save.item" = "Opdater";
"account.save.item" = "Opdater e-mail";
"account.save.prompt" = "Autentificer for at gemme ændringer";
"account.save.success" = "Din e-mailadresse er blevet gemt.";
"account.update.email.require.password.button" = "Indsend";
"account.update.email.require.password.message" = "Af sikkerhedsårsager skal vi bruge din PIA-adgangskode for at udføre en ændring i din konto. Angiv din PIA-adgangskode for at fortsætte.";
"account.update.email.require.password.title" = "PIA-adgangskode påkrævet";
"account.username.caption" = "Brugernavn";
"content_blocker.body.footer" = "Bemærk: Du behøver ikke have forbindelse til VPN for, at denne Indholdsblokering kan fungere, men den virker kun, når du anvender Safari-browseren.";
"content_blocker.body.subtitle" = "For at aktivere vores Indholdsblokering til brug med Safari skal du gå til Indstillinger > Safari og under Generelt trykke på Indholdsblokering til for PIA VPN.";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "Tippen, um Passwort anzuzeigen";
"account.email.caption" = "E-Mail";
"account.email.placeholder" = "E-Mail-Adresse";
"account.error.unauthorized" = "Dein Benutzername oder Passwort ist falsch.";
"account.expiry_date.expired" = "Dein Tarif ist abgelaufen.";
"account.expiry_date.information" = "Dein Tarif lauft am %@ ab.";
"account.eye.footer" = "Auf Augensymbol klicken, um dein Passwort ein- oder auszublenden.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "Kauf wiederherstellen";
"account.restore.title" = "Nicht gutgeschriebenen Kauf wiederherstellen";
"account.reveal.prompt" = "Zum Aufdecken authentifizieren";
"account.save.item" = "Aktualisieren";
"account.save.item" = "E-Mail aktualisieren";
"account.save.prompt" = "Authentifizieren, um die Änderungen zu speichern";
"account.save.success" = "Deine E-Mail-Adresse wurde gespeichert.";
"account.update.email.require.password.button" = "Senden";
"account.update.email.require.password.message" = "Aus Sicherheitsgründen benötigen wir Ihr PIA-Passwort, um eine Änderung Ihres Kontos vorzunehmen. Bitte Ihr PIA-Passwort eingeben, um fortzufahren.";
"account.update.email.require.password.title" = "PIA-Passwort erforderlich";
"account.username.caption" = "Benutzername";
"content_blocker.body.footer" = "Hinweis: Für diesen Inhalts-Blocker müssen Sie nicht mit VPN verbunden sein. Er funktioniert jedoch nur in Safari.";
"content_blocker.body.subtitle" = "Um unseren Inhalts-Blocker für Safari zu aktivieren, gehen Sie bitte zu Einstellungen > Safari > Allgemein > Inhalts-Blocker und schalten Sie PIA VPN ein.";
......
......@@ -87,7 +87,7 @@
"account.restore.button" = "RESTORE PURCHASE";
"account.restore.failure.title" = "Restore purchase";
"account.restore.failure.message" = "No redeemable purchase was found for renewal.";
"account.save.item" = "Update";
"account.save.item" = "Update email";
"account.save.prompt" = "Authenticate to save changes";
"account.save.success" = "Your email address has been saved.";
"account.reveal.prompt" = "Authenticate to reveal";
......@@ -96,6 +96,10 @@
"account.accessibility.eye.hint.conceal" = "Tap to conceal password";
"account.expiry_date.information" = "Your plan will expire on %@.";
"account.expiry_date.expired" = "Your plan has expired.";
"account.update.email.require.password.title" = "PIA Password Required";
"account.update.email.require.password.message" = "For security reasons we require your PIA password to perform a change in your account. Please input your PIA password to proceed.";
"account.update.email.require.password.button" = "Submit";
"account.error.unauthorized" = "Your username or password is incorrect.";
// SETTINGS
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "Toca para mostrar la contraseña";
"account.email.caption" = "Correo electrónico";
"account.email.placeholder" = "Dirección de correo electrónico";
"account.error.unauthorized" = "Tu nombre de usuario o contraseña son incorrectos.";
"account.expiry_date.expired" = "Su plan ya expiró.";
"account.expiry_date.information" = "Su plan va a expirar el %@.";
"account.eye.footer" = "Toca el icono de ojo para mostrar u ocultar tu contraseña.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "Restablecer compra";
"account.restore.title" = "Restablecer compra no acreditada ";
"account.reveal.prompt" = "Autenticar para revelar";
"account.save.item" = "Actualizar";
"account.save.item" = "Actualizar email";
"account.save.prompt" = "Autentica para guardar los cambios";
"account.save.success" = "Tu dirección de email se ha guardado.";
"account.update.email.require.password.button" = "Enviar";
"account.update.email.require.password.message" = "Por motivos de seguridad, solicitamos tu contraseña de PIA para realizar un cambio en tu cuenta. Introduce la contraseña de PIA para continuar.";
"account.update.email.require.password.title" = "Se requiere contraseña de PIA";
"account.username.caption" = "Nombre de usuario";
"content_blocker.body.footer" = "Por favor, considera que no tienes que estar conectado a la VPN para que funcione este Bloqueador de contenido, pero solo funcionará mientras navegas con Safari.";
"content_blocker.body.subtitle" = "Para habilitar el uso de nuestro Bloqueador de contenido con Safari, por favor, ve a Configuración > Safari, y bajo General toca el interruptor de Bloqueadores de contenido en PIA VPN.";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "Toucher pour afficher le mot de passe";
"account.email.caption" = "E-mail";
"account.email.placeholder" = "Adresse e-mail";
"account.error.unauthorized" = "Votre nom d'utilisateur ou mot de passe est incorrect.";
"account.expiry_date.expired" = "Votre forfait a expiré.";
"account.expiry_date.information" = "Votre forfait expirera le %@.";
"account.eye.footer" = "Touchez l'icône d'œil pour afficher ou masquer votre mot de passe.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "Restaurer l'achat";
"account.restore.title" = "Restaurer l'achat non crédité";
"account.reveal.prompt" = "Authentifiez-vous pour afficher";
"account.save.item" = "Mettre à jour";
"account.save.item" = "MàJ l'e-mail";
"account.save.prompt" = "Authentifiez-vous pour enregistrer les modifications";
"account.save.success" = "Votre adresse e-mail a été enregistrée.";
"account.update.email.require.password.button" = "Envoyer";
"account.update.email.require.password.message" = "Pour des raisons de sécurité, nous exigeons votre mot de passe PIA pour effectuer un changement sur votre compte. Veuillez saisir votre mot de passe PIA pour continuer.";
"account.update.email.require.password.title" = "Mot de passe PIA nécessaire";
"account.username.caption" = "Nom d'utilisateur";
"content_blocker.body.footer" = "Veuillez noter : vous n'avez pas besoin d'être connecté au VPN pour que ce bloqueur de contenu fonctionne, mais il ne fonctionnera qu'en naviguant avec Safari.";
"content_blocker.body.subtitle" = "Pour activer l'utilisation de notre bloqueur de contenu sur Safari, veuillez accéder aux Réglages > Safari et dans la section Général, activez le bouton Bloqueurs de contenu sur PIA VPN.";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "Tocca per rivelare la password";
"account.email.caption" = "Email";
"account.email.placeholder" = "Indirizzo email";
"account.error.unauthorized" = "Nome utente o password non valida";
"account.expiry_date.expired" = "Il tuo piano è scaduto.";
"account.expiry_date.information" = "Il tuo piano scade il %@.";
"account.eye.footer" = "Tocca l'icona con l'occhio per mostrare o nascondere la tua password.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "Ripristina acquisto";
"account.restore.title" = "Ripristina acquisto non accreditato";
"account.reveal.prompt" = "Autentica per rivelare";
"account.save.item" = "Aggiorna";
"account.save.item" = "Aggiorna email";
"account.save.prompt" = "Autentica per salvare le modifiche";
"account.save.success" = "Il tuo indirizzo email è stato salvato.";
"account.update.email.require.password.button" = "Invia";
"account.update.email.require.password.message" = "Per motivi di sicurezza, abbiamo bisogno che la tua password PIA completi una modifica sul tuo account. Inserisci la password PIA per continuare.";
"account.update.email.require.password.title" = "Necessaria password PIA";
"account.username.caption" = "Nome utente";
"content_blocker.body.footer" = "Nota bene: Non c'è bisogno di essere connessi alla VPN affinché il blocco dei contenuti sia attivo, ma il blocco avrà effetto solo navigando con Safari.";
"content_blocker.body.subtitle" = "Per abilitare il nostro Blocco dei contenuti in Safari, per favore vai su Impostazioni > Safari, e in Blocchi dei contenuti nella sezione Generali aziona PIA VPN.";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "タップしてパスワードを表示";
"account.email.caption" = "メールアドレス";
"account.email.placeholder" = "メールアドレス";
"account.error.unauthorized" = "ユーザー名またはパスワードが間違っています。";
"account.expiry_date.expired" = "プランが期限切れとなりました。";
"account.expiry_date.information" = "プランが%@に期限切れとなります。";
"account.eye.footer" = "目のアイコンをタップして、パスワードを表示または非表示にします。";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "購入を復元";
"account.restore.title" = "追加されていない購入を復元";
"account.reveal.prompt" = "認証して表示";
"account.save.item" = "アップデート";
"account.save.item" = "メールアドレス変更";
"account.save.prompt" = "認証して変更を保存";
"account.save.success" = "メールアドレスが保存されました。";
"account.update.email.require.password.button" = "送信";
"account.update.email.require.password.message" = "安全のため、お使いのアカウントのPIAパスワードの変更を行う必要があります。先へ進むにはPIAパスワードを入力してください。";
"account.update.email.require.password.title" = "PIAパスワードが必要です";
"account.username.caption" = "ユーザー名";
"content_blocker.body.footer" = "注意:コンテンツブロッカーは、VPNへの接続がなくても機能しますが、Safariを使ったブラウジングのみで利用できます。";
"content_blocker.body.subtitle" = "コンテンツブロッカーをオンにしてSafariで使えるようにするには、「設定」>「Safari」にアクセスし、「一般」からPIA VPNで「コンテンツブロッカー」をオンにしてください。";
......
......@@ -6,6 +6,7 @@
"account.accessibility.eye.hint.reveal" = "비밀번호를 표시하려면 누르세요";
"account.email.caption" = "이메일";
"account.email.placeholder" = "이메일 주소";
"account.error.unauthorized" = "사용자명 또는 비밀번호가 틀립니다.";
"account.expiry_date.expired" = "현재 플랜이 만료되었습니다.";
"account.expiry_date.information" = "현재 플랜이 %@에 만료됩니다.";
"account.eye.footer" = "눈 아이콘을 눌러서 비밀번호를 표시하거나 숨깁니다.";
......@@ -17,9 +18,12 @@
"account.restore.failure.title" = "구매 항목 복원";
"account.restore.title" = "인정되지 않은 구매 항목 복원";
"account.reveal.prompt" = "인증해서 표시합니다";
"account.save.item" = "업데이트";
"account.save.item" = "이메일 업데이트";
"account.save.prompt" = "인증해서 변경 사항을 저장합니다";
"account.save.success" = "이메일 주소가 저장되었습니다.";
"account.update.email.require.password.button" = "제출";
"account.update.email.require.password.message" = "보안상의 이유로 계정에서 변경 작업을 수행하려면 PIA 비밀번호가 필요합니다. 계속 진행하려면 PIA 비밀번호를 입력하세요.";
"account.update.email.require.password.title" = "PIA 비밀번호가 필요합니다.";
"account.username.caption" = "사용자 이름";
"content_blocker.body.footer" = "주의: Content Blocker를 작동시키기 위해 VPN에 연결할 필요가 없지만, Safari로 검색할 때만 작동합니다.";
"content_blocker.body.subtitle" = "Content Blocker를 활성화하여 Safari로 사용하려면 설정 > Safari로 가서 '일반'에서 Content Blockers를 눌러 PIA VPN을 켜세요.";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment