mirror of
https://github.com/aliasvault/aliasvault.git
synced 2025-12-23 22:28:22 -05:00
Refactor browser extension i18n to use single file structure (#1006)
This commit is contained in:
committed by
Leendert de Borst
parent
32e6ca597a
commit
25ff5bf994
@@ -2,7 +2,7 @@ import { type Browser } from '@wxt-dev/browser';
|
||||
import { sendMessage } from 'webext-bridge/background';
|
||||
|
||||
import { PasswordGenerator } from '@/utils/dist/shared/password-generator';
|
||||
import { tc } from '@/utils/i18n/StandaloneI18n';
|
||||
import { t } from '@/utils/i18n/StandaloneI18n';
|
||||
|
||||
import { browser } from "#imports";
|
||||
|
||||
@@ -21,7 +21,7 @@ export async function setupContextMenus() : Promise<void> {
|
||||
browser.contextMenus.create({
|
||||
id: "aliasvault-activate-form",
|
||||
parentId: "aliasvault-root",
|
||||
title: await tc('autofillWithAliasVault'),
|
||||
title: await t('content.autofillWithAliasVault'),
|
||||
contexts: ["editable"],
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function setupContextMenus() : Promise<void> {
|
||||
browser.contextMenus.create({
|
||||
id: "aliasvault-generate-password",
|
||||
parentId: "aliasvault-root",
|
||||
title: await tc('generateRandomPassword'),
|
||||
title: await t('content.generateRandomPassword'),
|
||||
contexts: ["all"]
|
||||
});
|
||||
|
||||
@@ -83,7 +83,7 @@ export function handleContextMenuClick(info: Browser.contextMenus.OnClickData, t
|
||||
*/
|
||||
async function copyPasswordToClipboard(generatedPassword: string) : Promise<void> {
|
||||
navigator.clipboard.writeText(generatedPassword).then(async () => {
|
||||
showToast(await tc('passwordCopiedToClipboard'));
|
||||
showToast(await t('content.passwordCopiedToClipboard'));
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ import { storage } from 'wxt/utils/storage';
|
||||
|
||||
import type { Vault, VaultResponse, VaultPostResponse } from '@/utils/dist/shared/models/webapi';
|
||||
import { EncryptionUtility } from '@/utils/EncryptionUtility';
|
||||
import { tc } from '@/utils/i18n/StandaloneI18n';
|
||||
import { t } from '@/utils/i18n/StandaloneI18n';
|
||||
import { SqliteClient } from '@/utils/SqliteClient';
|
||||
import { BoolResponse as messageBoolResponse } from '@/utils/types/messaging/BoolResponse';
|
||||
import { CredentialsResponse as messageCredentialsResponse } from '@/utils/types/messaging/CredentialsResponse';
|
||||
@@ -59,7 +59,7 @@ export async function handleCheckAuthStatus() : Promise<{ isLoggedIn: boolean, i
|
||||
isLoggedIn,
|
||||
isVaultLocked,
|
||||
hasPendingMigrations: false,
|
||||
error: error instanceof Error ? error.message : await tc('errors.unknownError', 'common')
|
||||
error: error instanceof Error ? error.message : await t('common.errors.unknownError')
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export async function handleStoreVault(
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Failed to store vault:', error);
|
||||
return { success: false, error: await tc('errors.failedToStoreVault', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToStoreVault') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ export async function handleSyncVault(
|
||||
const statusResponse = await webApi.getStatus();
|
||||
const statusError = webApi.validateStatusResponse(statusResponse);
|
||||
if (statusError !== null) {
|
||||
return { success: false, error: await tc(statusError) };
|
||||
return { success: false, error: await t('common.errors.' + statusError) };
|
||||
}
|
||||
|
||||
const vaultRevisionNumber = await storage.getItem('session:vaultRevisionNumber') as number;
|
||||
@@ -148,7 +148,7 @@ export async function handleGetVault(
|
||||
|
||||
if (!encryptedVault) {
|
||||
console.error('Vault not available');
|
||||
return { success: false, error: await tc('errors.vaultNotAvailable', 'common') };
|
||||
return { success: false, error: await t('common.errors.vaultNotAvailable') };
|
||||
}
|
||||
|
||||
const decryptedVault = await EncryptionUtility.symmetricDecrypt(
|
||||
@@ -165,7 +165,7 @@ export async function handleGetVault(
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Failed to get vault:', error);
|
||||
return { success: false, error: await tc('errors.failedToGetVault', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToGetVault') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ export async function handleGetCredentials(
|
||||
const derivedKey = await storage.getItem('session:derivedKey') as string;
|
||||
|
||||
if (!derivedKey) {
|
||||
return { success: false, error: await tc('errors.vaultIsLocked', 'common') };
|
||||
return { success: false, error: await t('common.errors.vaultIsLocked') };
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -202,7 +202,7 @@ export async function handleGetCredentials(
|
||||
return { success: true, credentials: credentials };
|
||||
} catch (error) {
|
||||
console.error('Error getting credentials:', error);
|
||||
return { success: false, error: await tc('errors.failedToGetCredentials', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToGetCredentials') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ export async function handleCreateIdentity(
|
||||
const derivedKey = await storage.getItem('session:derivedKey') as string;
|
||||
|
||||
if (!derivedKey) {
|
||||
return { success: false, error: await tc('errors.vaultIsLocked', 'common') };
|
||||
return { success: false, error: await t('common.errors.vaultIsLocked') };
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -230,7 +230,7 @@ export async function handleCreateIdentity(
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Failed to create identity:', error);
|
||||
return { success: false, error: await tc('errors.failedToCreateIdentity', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToCreateIdentity') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ export function handleGetDefaultEmailDomain(): Promise<stringResponse> {
|
||||
return { success: true, value: defaultEmailDomain ?? undefined };
|
||||
} catch (error) {
|
||||
console.error('Error getting default email domain:', error);
|
||||
return { success: false, error: await tc('errors.failedToGetDefaultEmailDomain', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToGetDefaultEmailDomain') };
|
||||
}
|
||||
})();
|
||||
}
|
||||
@@ -296,7 +296,7 @@ export async function handleGetDefaultIdentitySettings(
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error getting default identity settings:', error);
|
||||
return { success: false, error: await tc('errors.failedToGetDefaultIdentitySettings', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToGetDefaultIdentitySettings') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ export async function handleGetPasswordSettings(
|
||||
return { success: true, settings: passwordSettings };
|
||||
} catch (error) {
|
||||
console.error('Error getting password settings:', error);
|
||||
return { success: false, error: await tc('errors.failedToGetPasswordSettings', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToGetPasswordSettings') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ export async function handleUploadVault(
|
||||
return { success: true, status: response.status, newRevisionNumber: response.newRevisionNumber };
|
||||
} catch (error) {
|
||||
console.error('Failed to upload vault:', error);
|
||||
return { success: false, error: await tc('errors.failedToUploadVault', 'common') };
|
||||
return { success: false, error: await t('common.errors.failedToUploadVault') };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ export async function handleUploadVault(
|
||||
export async function handlePersistFormValues(data: any): Promise<void> {
|
||||
const derivedKey = await storage.getItem('session:derivedKey') as string;
|
||||
if (!derivedKey) {
|
||||
throw new Error(await tc('errors.noDerivedKeyAvailable', 'common'));
|
||||
throw new Error(await t('common.errors.noDerivedKeyAvailable'));
|
||||
}
|
||||
|
||||
// Always stringify the data properly
|
||||
@@ -442,7 +442,7 @@ async function uploadNewVaultToServer(sqliteClient: SqliteClient) : Promise<Vaul
|
||||
if (response.status === 0) {
|
||||
await storage.setItem('session:vaultRevisionNumber', response.newRevisionNumber);
|
||||
} else {
|
||||
throw new Error(await tc('errors.failedToUploadVaultToServer', 'common'));
|
||||
throw new Error(await t('common.errors.failedToUploadVaultToServer'));
|
||||
}
|
||||
|
||||
return response;
|
||||
@@ -455,7 +455,7 @@ async function createVaultSqliteClient() : Promise<SqliteClient> {
|
||||
const encryptedVault = await storage.getItem('session:encryptedVault') as string;
|
||||
const derivedKey = await storage.getItem('session:derivedKey') as string;
|
||||
if (!encryptedVault || !derivedKey) {
|
||||
throw new Error(await tc('errors.noVaultOrDerivedKeyFound', 'common'));
|
||||
throw new Error(await t('common.errors.noVaultOrDerivedKeyFound'));
|
||||
}
|
||||
|
||||
// Decrypt the vault.
|
||||
|
||||
@@ -5,11 +5,11 @@ import { injectIcon, popupDebounceTimeHasPassed, validateInputField } from '@/en
|
||||
import { isAutoShowPopupEnabled, openAutofillPopup, removeExistingPopup, createUpgradeRequiredPopup } from '@/entrypoints/contentScript/Popup';
|
||||
|
||||
import { FormDetector } from '@/utils/formDetector/FormDetector';
|
||||
import { t } from '@/utils/i18n/StandaloneI18n';
|
||||
import { BoolResponse as messageBoolResponse } from '@/utils/types/messaging/BoolResponse';
|
||||
|
||||
import { defineContentScript } from '#imports';
|
||||
import { createShadowRootUi } from '#imports';
|
||||
import { tc } from '@/utils/i18n/StandaloneI18n';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
@@ -160,7 +160,7 @@ export default defineContentScript({
|
||||
|
||||
if (authStatus.hasPendingMigrations) {
|
||||
// Show upgrade required popup
|
||||
await createUpgradeRequiredPopup(inputElement, container, await tc('vaultUpgradeRequired'));
|
||||
await createUpgradeRequiredPopup(inputElement, container, await t('content.vaultUpgradeRequired'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { CreateIdentityGenerator } from '@/utils/dist/shared/identity-generator'
|
||||
import type { Credential } from '@/utils/dist/shared/models/vault';
|
||||
import { CreatePasswordGenerator, PasswordGenerator } from '@/utils/dist/shared/password-generator';
|
||||
import { FormDetector } from '@/utils/formDetector/FormDetector';
|
||||
import { tc } from '@/utils/i18n/StandaloneI18n';
|
||||
import { t } from '@/utils/i18n/StandaloneI18n';
|
||||
import { SqliteClient } from '@/utils/SqliteClient';
|
||||
import { CredentialsResponse } from '@/utils/types/messaging/CredentialsResponse';
|
||||
import { IdentitySettingsResponse } from '@/utils/types/messaging/IdentitySettingsResponse';
|
||||
@@ -157,13 +157,13 @@ export function removeExistingPopup(container: HTMLElement) : void {
|
||||
*/
|
||||
export async function createAutofillPopup(input: HTMLInputElement, credentials: Credential[] | undefined, rootContainer: HTMLElement) : Promise<void> {
|
||||
// Get all translations first
|
||||
const newText = await tc('new');
|
||||
const searchPlaceholder = await tc('searchVault');
|
||||
const hideFor1HourText = await tc('hideFor1Hour');
|
||||
const hidePermanentlyText = await tc('hidePermanently');
|
||||
const noMatchesText = await tc('noMatchesFound');
|
||||
const creatingText = await tc('creatingNewAlias');
|
||||
const failedText = await tc('failedToCreateIdentity');
|
||||
const newText = await t('content.new');
|
||||
const searchPlaceholder = await t('content.searchVault');
|
||||
const hideFor1HourText = await t('content.hideFor1Hour');
|
||||
const hidePermanentlyText = await t('content.hidePermanently');
|
||||
const noMatchesText = await t('content.noMatchesFound');
|
||||
const creatingText = await t('content.creatingNewAlias');
|
||||
const failedText = await t('content.failedToCreateIdentity');
|
||||
|
||||
// Disable browser's native autocomplete to avoid conflicts with AliasVault's autocomplete.
|
||||
input.setAttribute('autocomplete', 'false');
|
||||
@@ -471,7 +471,7 @@ export async function createVaultLockedPopup(input: HTMLInputElement, rootContai
|
||||
// Add message
|
||||
const messageElement = document.createElement('div');
|
||||
messageElement.className = 'av-vault-locked-message';
|
||||
messageElement.textContent = await tc('vaultLocked');
|
||||
messageElement.textContent = await t('content.vaultLocked');
|
||||
container.appendChild(messageElement);
|
||||
|
||||
// Add unlock button with SVG icon
|
||||
@@ -771,10 +771,10 @@ export async function createAliasCreationPopup(suggestedNames: string[], rootCon
|
||||
<circle cx="16" cy="16" r="1"/>
|
||||
</svg>
|
||||
`;
|
||||
const randomIdentitySubtext = await tc('randomIdentityDescription');
|
||||
const randomIdentityTitle = await tc('createRandomAlias');
|
||||
const randomIdentityTitleDropdown = await tc('randomAlias');
|
||||
const randomIdentitySubtextDropdown = await tc('randomIdentityDescriptionDropdown');
|
||||
const randomIdentitySubtext = await t('content.randomIdentityDescription');
|
||||
const randomIdentityTitle = await t('content.createRandomAlias');
|
||||
const randomIdentityTitleDropdown = await t('content.randomAlias');
|
||||
const randomIdentitySubtextDropdown = await t('content.randomIdentityDescriptionDropdown');
|
||||
|
||||
const manualUsernamePasswordIcon = `
|
||||
<svg class="av-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
@@ -782,24 +782,24 @@ export async function createAliasCreationPopup(suggestedNames: string[], rootCon
|
||||
<path d="M5.5 20a6.5 6.5 0 0 1 13 0"/>
|
||||
</svg>
|
||||
`;
|
||||
const manualUsernamePasswordSubtext = await tc('manualCredentialDescription');
|
||||
const manualUsernamePasswordTitle = await tc('createUsernamePassword');
|
||||
const manualUsernamePasswordTitleDropdown = await tc('usernamePassword');
|
||||
const manualUsernamePasswordSubtextDropdown = await tc('manualCredentialDescriptionDropdown');
|
||||
const manualUsernamePasswordSubtext = await t('content.manualCredentialDescription');
|
||||
const manualUsernamePasswordTitle = await t('content.createUsernamePassword');
|
||||
const manualUsernamePasswordTitleDropdown = await t('content.usernamePassword');
|
||||
const manualUsernamePasswordSubtextDropdown = await t('content.manualCredentialDescriptionDropdown');
|
||||
|
||||
// Get all translated strings first
|
||||
const serviceNameText = await tc('serviceName');
|
||||
const enterServiceNameText = await tc('enterServiceName');
|
||||
const cancelText = await tc('cancel');
|
||||
const createAndSaveAliasText = await tc('createAndSaveAlias');
|
||||
const emailText = await tc('email');
|
||||
const enterEmailAddressText = await tc('enterEmailAddress');
|
||||
const usernameText = await tc('username');
|
||||
const enterUsernameText = await tc('enterUsername');
|
||||
const generatedPasswordText = await tc('generatedPassword');
|
||||
const generateNewPasswordText = await tc('generateNewPassword');
|
||||
const togglePasswordVisibilityText = await tc('togglePasswordVisibility');
|
||||
const createAndSaveCredentialText = await tc('createAndSaveCredential');
|
||||
const serviceNameText = await t('content.serviceName');
|
||||
const enterServiceNameText = await t('content.enterServiceName');
|
||||
const cancelText = await t('content.cancel');
|
||||
const createAndSaveAliasText = await t('content.createAndSaveAlias');
|
||||
const emailText = await t('content.email');
|
||||
const enterEmailAddressText = await t('content.enterEmailAddress');
|
||||
const usernameText = await t('content.username');
|
||||
const enterUsernameText = await t('content.enterUsername');
|
||||
const generatedPasswordText = await t('content.generatedPassword');
|
||||
const generateNewPasswordText = await t('content.generateNewPassword');
|
||||
const togglePasswordVisibilityText = await t('content.togglePasswordVisibility');
|
||||
const createAndSaveCredentialText = await t('content.createAndSaveCredential');
|
||||
|
||||
// Create the main content
|
||||
popup.innerHTML = `
|
||||
@@ -1163,14 +1163,14 @@ export async function createAliasCreationPopup(suggestedNames: string[], rootCon
|
||||
if (!emailLabel.querySelector('.av-create-popup-error-text')) {
|
||||
const emailError = document.createElement('span');
|
||||
emailError.className = 'av-create-popup-error-text';
|
||||
emailError.textContent = await tc('enterEmailAndOrUsername');
|
||||
emailError.textContent = await t('content.enterEmailAndOrUsername');
|
||||
emailLabel.appendChild(emailError);
|
||||
}
|
||||
|
||||
if (!usernameLabel.querySelector('.av-create-popup-error-text')) {
|
||||
const usernameError = document.createElement('span');
|
||||
usernameError.className = 'av-create-popup-error-text';
|
||||
usernameError.textContent = await tc('enterEmailAndOrUsername');
|
||||
usernameError.textContent = await t('content.enterEmailAndOrUsername');
|
||||
usernameLabel.appendChild(usernameError);
|
||||
}
|
||||
|
||||
@@ -1525,7 +1525,7 @@ export async function createUpgradeRequiredPopup(input: HTMLInputElement, rootCo
|
||||
|
||||
// Add upgrade button with SVG icon
|
||||
const button = document.createElement('button');
|
||||
button.title = await tc('openAliasVaultToUpgrade');
|
||||
button.title = await t('content.openAliasVaultToUpgrade');
|
||||
button.className = 'av-upgrade-required-button';
|
||||
button.innerHTML = `
|
||||
<svg class="av-icon-upgrade" viewBox="0 0 24 24">
|
||||
@@ -1540,7 +1540,7 @@ export async function createUpgradeRequiredPopup(input: HTMLInputElement, rootCo
|
||||
// Add close button as a separate element positioned to the right
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.className = 'av-button av-button-close av-upgrade-required-close';
|
||||
closeButton.title = await tc('dismissPopup');
|
||||
closeButton.title = await t('content.dismissPopup');
|
||||
closeButton.innerHTML = `
|
||||
<svg class="av-icon" viewBox="0 0 24 24">
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
|
||||
@@ -42,7 +42,7 @@ type RouteConfig = {
|
||||
* App component.
|
||||
*/
|
||||
const App: React.FC = () => {
|
||||
const { t } = useTranslation(['common', 'credentials', 'emails', 'settings']);
|
||||
const { t } = useTranslation();
|
||||
const authContext = useAuth();
|
||||
const { isInitialLoading } = useLoading();
|
||||
const [isLoading, setIsLoading] = useMinDurationLoading(true, 150);
|
||||
@@ -57,13 +57,13 @@ const App: React.FC = () => {
|
||||
{ path: '/unlock', element: <Unlock />, showBackButton: false },
|
||||
{ path: '/unlock-success', element: <UnlockSuccess />, showBackButton: false },
|
||||
{ path: '/upgrade', element: <Upgrade />, showBackButton: false },
|
||||
{ path: '/auth-settings', element: <AuthSettings />, showBackButton: true, title: t('settings:title') },
|
||||
{ path: '/auth-settings', element: <AuthSettings />, showBackButton: true, title: t('settings.title') },
|
||||
{ path: '/credentials', element: <CredentialsList />, showBackButton: false },
|
||||
{ path: '/credentials/add', element: <CredentialAddEdit />, showBackButton: true, title: t('credentials:addCredential') },
|
||||
{ path: '/credentials/:id', element: <CredentialDetails />, showBackButton: true, title: t('credentials:credentialDetails') },
|
||||
{ path: '/credentials/:id/edit', element: <CredentialAddEdit />, showBackButton: true, title: t('credentials:editCredential') },
|
||||
{ path: '/credentials/add', element: <CredentialAddEdit />, showBackButton: true, title: t('credentials.addCredential') },
|
||||
{ path: '/credentials/:id', element: <CredentialDetails />, showBackButton: true, title: t('credentials.credentialDetails') },
|
||||
{ path: '/credentials/:id/edit', element: <CredentialAddEdit />, showBackButton: true, title: t('credentials.editCredential') },
|
||||
{ path: '/emails', element: <EmailsList />, showBackButton: false },
|
||||
{ path: '/emails/:id', element: <EmailDetails />, showBackButton: true, title: t('emails:title') },
|
||||
{ path: '/emails/:id', element: <EmailDetails />, showBackButton: true, title: t('emails.title') },
|
||||
{ path: '/settings', element: <Settings />, showBackButton: false },
|
||||
{ path: '/logout', element: <Logout />, showBackButton: false },
|
||||
];
|
||||
|
||||
@@ -14,7 +14,7 @@ type AliasBlockProps = {
|
||||
* Render the alias block.
|
||||
*/
|
||||
const AliasBlock: React.FC<AliasBlockProps> = ({ credential }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const hasFirstName = Boolean(credential.Alias?.FirstName?.trim());
|
||||
const hasLastName = Boolean(credential.Alias?.LastName?.trim());
|
||||
const hasNickName = Boolean(credential.Alias?.NickName?.trim());
|
||||
@@ -26,39 +26,39 @@ const AliasBlock: React.FC<AliasBlockProps> = ({ credential }) => {
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('alias')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('common.alias')}</h2>
|
||||
{(hasFirstName || hasLastName) && (
|
||||
<FormInputCopyToClipboard
|
||||
id="fullName"
|
||||
label={t('fullName')}
|
||||
label={t('common.fullName')}
|
||||
value={[credential.Alias?.FirstName, credential.Alias?.LastName].filter(Boolean).join(' ')}
|
||||
/>
|
||||
)}
|
||||
{hasFirstName && (
|
||||
<FormInputCopyToClipboard
|
||||
id="firstName"
|
||||
label={t('firstName')}
|
||||
label={t('common.firstName')}
|
||||
value={credential.Alias?.FirstName ?? ''}
|
||||
/>
|
||||
)}
|
||||
{hasLastName && (
|
||||
<FormInputCopyToClipboard
|
||||
id="lastName"
|
||||
label={t('lastName')}
|
||||
label={t('common.lastName')}
|
||||
value={credential.Alias?.LastName ?? ''}
|
||||
/>
|
||||
)}
|
||||
{hasBirthDate && (
|
||||
<FormInputCopyToClipboard
|
||||
id="birthDate"
|
||||
label={t('birthDate')}
|
||||
label={t('common.birthDate')}
|
||||
value={IdentityHelperUtils.normalizeBirthDateForDisplay(credential.Alias?.BirthDate)}
|
||||
/>
|
||||
)}
|
||||
{hasNickName && (
|
||||
<FormInputCopyToClipboard
|
||||
id="nickName"
|
||||
label={t('nickname')}
|
||||
label={t('common.nickname')}
|
||||
value={credential.Alias?.NickName ?? ''}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -13,7 +13,7 @@ type LoginCredentialsBlockProps = {
|
||||
* Render the login credentials block.
|
||||
*/
|
||||
const LoginCredentialsBlock: React.FC<LoginCredentialsBlockProps> = ({ credential }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const email = credential.Alias?.Email?.trim();
|
||||
const username = credential.Username?.trim();
|
||||
const password = credential.Password?.trim();
|
||||
@@ -24,25 +24,25 @@ const LoginCredentialsBlock: React.FC<LoginCredentialsBlockProps> = ({ credentia
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('loginCredentials')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('common.loginCredentials')}</h2>
|
||||
{email && (
|
||||
<FormInputCopyToClipboard
|
||||
id="email"
|
||||
label={t('email')}
|
||||
label={t('common.email')}
|
||||
value={email}
|
||||
/>
|
||||
)}
|
||||
{username && (
|
||||
<FormInputCopyToClipboard
|
||||
id="username"
|
||||
label={t('username')}
|
||||
label={t('common.username')}
|
||||
value={username}
|
||||
/>
|
||||
)}
|
||||
{password && (
|
||||
<FormInputCopyToClipboard
|
||||
id="password"
|
||||
label={t('password')}
|
||||
label={t('common.password')}
|
||||
value={password}
|
||||
type="password"
|
||||
/>
|
||||
|
||||
@@ -21,7 +21,7 @@ const convertUrlsToLinks = (text: string): string => {
|
||||
* Render the notes block.
|
||||
*/
|
||||
const NotesBlock: React.FC<NotesBlockProps> = ({ notes }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
if (!notes) {
|
||||
return null;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ const NotesBlock: React.FC<NotesBlockProps> = ({ notes }) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('notes')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-2">{t('common.notes')}</h2>
|
||||
<div className="p-4 bg-gray-50 rounded-lg dark:bg-gray-700">
|
||||
<p
|
||||
className="text-gray-900 dark:text-gray-100 whitespace-pre-wrap"
|
||||
|
||||
@@ -14,7 +14,7 @@ type TotpBlockProps = {
|
||||
* This component shows TOTP codes for a credential.
|
||||
*/
|
||||
const TotpBlock: React.FC<TotpBlockProps> = ({ credentialId }) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const [totpCodes, setTotpCodes] = useState<TotpCode[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [currentCodes, setCurrentCodes] = useState<Record<string, string>>({});
|
||||
@@ -140,8 +140,8 @@ const TotpBlock: React.FC<TotpBlockProps> = ({ credentialId }) => {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="text-gray-500 dark:text-gray-400 mb-4">
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{t('twoFactorAuthentication')}</h2>
|
||||
{t('loadingTotpCodes')}
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{t('common.twoFactorAuthentication')}</h2>
|
||||
{t('common.loadingTotpCodes')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -153,7 +153,7 @@ const TotpBlock: React.FC<TotpBlockProps> = ({ credentialId }) => {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">{t('twoFactorAuthentication')}</h2>
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">{t('common.twoFactorAuthentication')}</h2>
|
||||
<div className="grid grid-cols-1 gap-2">
|
||||
{totpCodes.map(totpCode => (
|
||||
<button
|
||||
@@ -173,7 +173,7 @@ const TotpBlock: React.FC<TotpBlockProps> = ({ credentialId }) => {
|
||||
</span>
|
||||
<div className="text-xs">
|
||||
{copiedId === totpCode.Id ? (
|
||||
<span className="text-green-600 dark:text-green-400">{t('copied')}</span>
|
||||
<span className="text-green-600 dark:text-green-400">{t('common.copied')}</span>
|
||||
) : (
|
||||
<span className="text-gray-500 dark:text-gray-400">{getRemainingSeconds()}s</span>
|
||||
)}
|
||||
|
||||
@@ -19,7 +19,7 @@ type EmailPreviewProps = {
|
||||
* This component shows a preview of the latest emails in the inbox.
|
||||
*/
|
||||
export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
const { t } = useTranslation(['common', 'emails']);
|
||||
const { t } = useTranslation();
|
||||
const [emails, setEmails] = useState<MailboxEmail[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [lastEmailId, setLastEmailId] = useState<number>(0);
|
||||
@@ -76,7 +76,7 @@ export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
setError(t('emails:errors.emailLoadError'));
|
||||
setError(t('emails.errors.emailLoadError'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,17 +125,17 @@ export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
} catch {
|
||||
// Try to parse as error response instead
|
||||
const apiErrorResponse = response as ApiErrorResponse;
|
||||
setError(t('emails:apiErrors.' + apiErrorResponse?.code));
|
||||
setError(t('emails.apiErrors.' + apiErrorResponse?.code));
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
setError(t('emails:errors.emailLoadError'));
|
||||
setError(t('emails.errors.emailLoadError'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error loading emails:', err);
|
||||
setError(t('emails:errors.emailUnexpectedError'));
|
||||
setError(t('emails.errors.emailUnexpectedError'));
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
@@ -155,7 +155,7 @@ export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
return (
|
||||
<div className="text-gray-500 dark:text-gray-400 mb-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common:recentEmails')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common.recentEmails')}</h2>
|
||||
</div>
|
||||
<div className="p-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded">
|
||||
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
|
||||
@@ -168,10 +168,10 @@ export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
return (
|
||||
<div className="text-gray-500 dark:text-gray-400 mb-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common:recentEmails')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common.recentEmails')}</h2>
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />
|
||||
</div>
|
||||
{t('common:loadingEmails')}
|
||||
{t('common.loadingEmails')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -179,10 +179,10 @@ export const EmailPreview: React.FC<EmailPreviewProps> = ({ email }) => {
|
||||
return (
|
||||
<div className="text-gray-500 dark:text-gray-400 mb-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common:recentEmails')}</h2>
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">{t('common.recentEmails')}</h2>
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />
|
||||
</div>
|
||||
{t('emails:noEmails')}
|
||||
{t('emails.noEmails')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(({
|
||||
showPassword: controlledShowPassword,
|
||||
onShowPasswordChange
|
||||
}, ref) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const [internalShowPassword, setInternalShowPassword] = React.useState(false);
|
||||
|
||||
/**
|
||||
@@ -114,7 +114,7 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(({
|
||||
* Toggle password visibility.
|
||||
*/
|
||||
onClick: (): void => setShowPassword(!showPassword),
|
||||
title: showPassword ? t('hidePassword') : t('showPassword')
|
||||
title: showPassword ? t('common.hidePassword') : t('common.showPassword')
|
||||
}]
|
||||
: buttons;
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ export const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> =
|
||||
value,
|
||||
type = 'text'
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
@@ -114,7 +114,7 @@ export const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> =
|
||||
<button
|
||||
type="button"
|
||||
className="p-1 text-green-500 dark:text-green-400 transition-colors duration-200"
|
||||
title={t('copied')}
|
||||
title={t('common.copied')}
|
||||
>
|
||||
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<Icon name="check" />
|
||||
@@ -125,7 +125,7 @@ export const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> =
|
||||
type="button"
|
||||
onClick={copyToClipboard}
|
||||
className="p-1 text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white transition-colors duration-200"
|
||||
title={t('copyToClipboard')}
|
||||
title={t('common.copyToClipboard')}
|
||||
>
|
||||
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<Icon name="copy" />
|
||||
@@ -137,7 +137,7 @@ export const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> =
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
className="p-1 text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white transition-colors duration-200"
|
||||
title={showPassword ? t('hidePassword') : t('showPassword')}
|
||||
title={showPassword ? t('common.hidePassword') : t('common.showPassword')}
|
||||
>
|
||||
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<Icon name={showPassword ? 'visibility-off' : 'visibility'} />
|
||||
|
||||
@@ -28,7 +28,7 @@ const LanguageSwitcher: React.FC<LanguageSwitcherProps> = ({
|
||||
variant = 'dropdown',
|
||||
size = 'md'
|
||||
}): React.JSX.Element => {
|
||||
const { i18n } = useTranslation('common');
|
||||
const { i18n } = useTranslation();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ type TabName = 'credentials' | 'emails' | 'settings';
|
||||
* Bottom nav component.
|
||||
*/
|
||||
const BottomNav: React.FC = () => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [currentTab, setCurrentTab] = useState<TabName>('credentials');
|
||||
@@ -62,7 +62,7 @@ const BottomNav: React.FC = () => {
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
||||
</svg>
|
||||
<span className="text-xs mt-1">{t('credentials:title', 'Credentials')}</span>
|
||||
<span className="text-xs mt-1">{t('menu.credentials')}</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleTabChange('emails')}
|
||||
@@ -73,7 +73,7 @@ const BottomNav: React.FC = () => {
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span className="text-xs mt-1">{t('emails:title', 'Emails')}</span>
|
||||
<span className="text-xs mt-1">{t('menu.emails')}</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleTabChange('settings')}
|
||||
@@ -85,7 +85,7 @@ const BottomNav: React.FC = () => {
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
<span className="text-xs mt-1">{t('settings:title', 'Settings')}</span>
|
||||
<span className="text-xs mt-1">{t('menu.settings')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@ const Header: React.FC<HeaderProps> = ({
|
||||
routes = [],
|
||||
rightButtons
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const authContext = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
@@ -88,7 +88,7 @@ const Header: React.FC<HeaderProps> = ({
|
||||
className="flex items-center hover:opacity-80 transition-opacity"
|
||||
>
|
||||
<img src="/assets/images/logo.svg" alt="AliasVault" className="h-8 w-8 mr-2" />
|
||||
<h1 className="text-gray-900 dark:text-white text-xl font-bold">{t('appName')}</h1>
|
||||
<h1 className="text-gray-900 dark:text-white text-xl font-bold">{t('common.appName')}</h1>
|
||||
{/* Hide beta badge on Safari as it's not allowed to show non-production badges */}
|
||||
{!import.meta.env.SAFARI && (
|
||||
<span className="text-primary-500 text-[10px] ml-1 font-normal">BETA</span>
|
||||
@@ -108,7 +108,7 @@ const Header: React.FC<HeaderProps> = ({
|
||||
onClick={(handleSettings)}
|
||||
className="p-1 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
>
|
||||
<span className="sr-only">{t('settings')}</span>
|
||||
<span className="sr-only">{t('common.settings')}</span>
|
||||
<svg className="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fillRule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clipRule="evenodd" />
|
||||
</svg>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useApiUrl } from '@/entrypoints/popup/utils/ApiUrlUtility';
|
||||
const LoginServerInfo: React.FC = () => {
|
||||
const { loadApiUrl, getDisplayUrl } = useApiUrl();
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('auth');
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
/**
|
||||
@@ -28,7 +28,7 @@ const LoginServerInfo: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div className="text-xs text-gray-600 dark:text-gray-400 mb-4">
|
||||
({t('connectingTo')}{' '}
|
||||
({t('auth.connectingTo')}{' '}
|
||||
<button
|
||||
onClick={handleClick}
|
||||
type="button"
|
||||
|
||||
@@ -25,7 +25,7 @@ const Modal: React.FC<IModalProps> = ({
|
||||
cancelText = '',
|
||||
variant = 'default'
|
||||
}) => {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ const Modal: React.FC<IModalProps> = ({
|
||||
className="absolute right-4 top-4 text-gray-400 hover:text-gray-500 focus:outline-none"
|
||||
onClick={onClose}
|
||||
>
|
||||
<span className="sr-only">{t('close')}</span>
|
||||
<span className="sr-only">{t('common.close')}</span>
|
||||
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
|
||||
@@ -23,9 +23,9 @@ export function useVaultMutate() : {
|
||||
isLoading: boolean;
|
||||
syncStatus: string;
|
||||
} {
|
||||
const { t } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [syncStatus, setSyncStatus] = useState(t('syncingVault'));
|
||||
const [syncStatus, setSyncStatus] = useState(t('common.syncingVault'));
|
||||
const dbContext = useDb();
|
||||
const { syncVault } = useVaultSync();
|
||||
|
||||
@@ -36,12 +36,12 @@ export function useVaultMutate() : {
|
||||
operation: () => Promise<void>,
|
||||
options: VaultMutationOptions
|
||||
) : Promise<void> => {
|
||||
setSyncStatus(t('savingChangesToVault'));
|
||||
setSyncStatus(t('common.savingChangesToVault'));
|
||||
|
||||
// Execute the provided operation (e.g. create/update/delete credential)
|
||||
await operation();
|
||||
|
||||
setSyncStatus(t('uploadingVaultToServer'));
|
||||
setSyncStatus(t('common.uploadingVaultToServer'));
|
||||
|
||||
try {
|
||||
// Upload the updated vault to the server.
|
||||
@@ -103,11 +103,11 @@ export function useVaultMutate() : {
|
||||
) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setSyncStatus(t('checkingVaultUpdates'));
|
||||
setSyncStatus(t('common.checkingVaultUpdates'));
|
||||
|
||||
// Skip sync check if requested (e.g., during upgrade operations)
|
||||
if (options.skipSyncCheck) {
|
||||
setSyncStatus(t('executingOperation'));
|
||||
setSyncStatus(t('common.executingOperation'));
|
||||
await executeMutateOperation(operation, options);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ type VaultSyncOptions = {
|
||||
export const useVaultSync = () : {
|
||||
syncVault: (options?: VaultSyncOptions) => Promise<boolean>;
|
||||
} => {
|
||||
const { tc } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const authContext = useAuth();
|
||||
const dbContext = useDb();
|
||||
const webApi = useWebApi();
|
||||
@@ -67,7 +67,7 @@ export const useVaultSync = () : {
|
||||
}
|
||||
|
||||
// Check app status and vault revision
|
||||
onStatus?.(await tc('checkingVaultUpdates'));
|
||||
onStatus?.(t('common.checkingVaultUpdates'));
|
||||
const statusResponse = await withMinimumDelay(() => webApi.getStatus(), 300, enableDelay);
|
||||
|
||||
// Check if server is actually available, 0.0.0 indicates connection error which triggers offline mode.
|
||||
@@ -77,7 +77,7 @@ export const useVaultSync = () : {
|
||||
|
||||
const statusError = webApi.validateStatusResponse(statusResponse);
|
||||
if (statusError) {
|
||||
onError?.(await tc(statusError));
|
||||
onError?.(t('common.errors.' + statusError));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export const useVaultSync = () : {
|
||||
const vaultRevisionNumber = vaultMetadata?.vaultRevisionNumber ?? 0;
|
||||
|
||||
if (statusResponse.vaultRevision > vaultRevisionNumber) {
|
||||
onStatus?.(await tc('syncingUpdatedVault'));
|
||||
onStatus?.(t('common.syncingUpdatedVault'));
|
||||
const vaultResponseJson = await withMinimumDelay(() => webApi.get<VaultResponse>('Vault'), 1000, enableDelay);
|
||||
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson as VaultResponse, t);
|
||||
@@ -171,7 +171,7 @@ export const useVaultSync = () : {
|
||||
onError?.(errorMessage);
|
||||
return false;
|
||||
}
|
||||
}, [authContext, dbContext, webApi, tc]);
|
||||
}, [authContext, dbContext, webApi, t]);
|
||||
|
||||
return { syncVault };
|
||||
};
|
||||
@@ -57,14 +57,14 @@ const createUrlSchema = (t: (key: string) => string): Yup.ObjectSchema<{apiUrl:
|
||||
* Auth settings page only shown when user is not logged in.
|
||||
*/
|
||||
const AuthSettings: React.FC = () => {
|
||||
const { t } = useTranslation('settings');
|
||||
const { t } = useTranslation();
|
||||
const [selectedOption, setSelectedOption] = useState<string>('');
|
||||
const [customUrl, setCustomUrl] = useState<string>('');
|
||||
const [customClientUrl, setCustomClientUrl] = useState<string>('');
|
||||
const [isGloballyEnabled, setIsGloballyEnabled] = useState<boolean>(true);
|
||||
const [errors, setErrors] = useState<{ apiUrl?: string; clientUrl?: string }>({});
|
||||
const { setIsInitialLoading } = useLoading();
|
||||
|
||||
|
||||
const urlSchema = createUrlSchema(t);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -176,14 +176,14 @@ const AuthSettings: React.FC = () => {
|
||||
{/* Language Settings Section */}
|
||||
<div className="mb-6">
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('language')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('common.language')}</p>
|
||||
<LanguageSwitcher variant="dropdown" size="sm" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
<label htmlFor="api-connection" className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-2">
|
||||
{t('serverUrl')}
|
||||
{t('common.serverUrl')}
|
||||
</label>
|
||||
<select
|
||||
value={selectedOption}
|
||||
@@ -238,7 +238,7 @@ const AuthSettings: React.FC = () => {
|
||||
{/* Autofill Popup Settings Section */}
|
||||
<div className="mb-6">
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('autofillEnabled')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('common.autofillEnabled')}</p>
|
||||
<button
|
||||
onClick={toggleGlobalPopup}
|
||||
className={`px-4 py-2 rounded-md transition-colors ${
|
||||
@@ -247,13 +247,13 @@ const AuthSettings: React.FC = () => {
|
||||
: 'bg-red-200 text-red-800 hover:bg-red-300 dark:bg-red-900/30 dark:text-red-400 dark:hover:bg-red-900/50'
|
||||
}`}
|
||||
>
|
||||
{isGloballyEnabled ? t('common:enabled', 'Enabled') : t('common:disabled', 'Disabled')}
|
||||
{isGloballyEnabled ? t('common.enabled', 'Enabled') : t('common.disabled', 'Disabled')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center text-gray-400 dark:text-gray-600">
|
||||
{t('version')}: {AppInfo.VERSION}
|
||||
{t('common.version')}: {AppInfo.VERSION}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@ const credentialSchema = Yup.object().shape({
|
||||
* Add or edit credential page.
|
||||
*/
|
||||
const CredentialAddEdit: React.FC = () => {
|
||||
const { t } = useTranslation(['common', 'credentials']);
|
||||
const { t } = useTranslation();
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const dbContext = useDb();
|
||||
@@ -460,14 +460,14 @@ const CredentialAddEdit: React.FC = () => {
|
||||
{isEditMode && (
|
||||
<HeaderButton
|
||||
onClick={() => setShowDeleteModal(true)}
|
||||
title={t('credentials:deleteCredential')}
|
||||
title={t('credentials.deleteCredential')}
|
||||
iconType={HeaderIconType.DELETE}
|
||||
variant="danger"
|
||||
/>
|
||||
)}
|
||||
<HeaderButton
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
title={t('credentials:saveCredential')}
|
||||
title={t('credentials.saveCredential')}
|
||||
iconType={HeaderIconType.SAVE}
|
||||
/>
|
||||
</div>
|
||||
@@ -483,7 +483,7 @@ const CredentialAddEdit: React.FC = () => {
|
||||
}, [setHeaderButtons]);
|
||||
|
||||
if (isEditMode && !watch('ServiceName')) {
|
||||
return <div>{t('common:loading')}</div>;
|
||||
return <div>{t('common.loading')}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -505,10 +505,10 @@ const CredentialAddEdit: React.FC = () => {
|
||||
setShowDeleteModal(false);
|
||||
void handleDelete();
|
||||
}}
|
||||
title={t('credentials:deleteCredentialTitle')}
|
||||
message={t('credentials:deleteCredentialConfirm')}
|
||||
confirmText={t('common:delete')}
|
||||
cancelText={t('common:cancel')}
|
||||
title={t('credentials.deleteCredentialTitle')}
|
||||
message={t('credentials.deleteCredentialConfirm')}
|
||||
confirmText={t('common.delete')}
|
||||
cancelText={t('common.cancel')}
|
||||
variant="danger"
|
||||
/>
|
||||
|
||||
@@ -529,7 +529,7 @@ const CredentialAddEdit: React.FC = () => {
|
||||
<circle cx="8" cy="16" r="1"/>
|
||||
<circle cx="16" cy="16" r="1"/>
|
||||
</svg>
|
||||
{t('credentials:randomAlias')}
|
||||
{t('credentials.randomAlias')}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@@ -542,18 +542,18 @@ const CredentialAddEdit: React.FC = () => {
|
||||
<circle cx="12" cy="7" r="4"/>
|
||||
<path d="M5.5 20a6.5 6.5 0 0 1 13 0"/>
|
||||
</svg>
|
||||
{t('credentials:manual')}
|
||||
{t('credentials.manual')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials:service')}</h2>
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials.service')}</h2>
|
||||
<div className="space-y-4">
|
||||
<FormInput
|
||||
id="serviceName"
|
||||
label={t('credentials:serviceName')}
|
||||
label={t('credentials.serviceName')}
|
||||
ref={serviceNameRef}
|
||||
value={watch('ServiceName') ?? ''}
|
||||
onChange={(value) => setValue('ServiceName', value)}
|
||||
@@ -562,7 +562,7 @@ const CredentialAddEdit: React.FC = () => {
|
||||
/>
|
||||
<FormInput
|
||||
id="serviceUrl"
|
||||
label={t('credentials:serviceUrl')}
|
||||
label={t('credentials.serviceUrl')}
|
||||
value={watch('ServiceUrl') ?? ''}
|
||||
onChange={(value) => setValue('ServiceUrl', value)}
|
||||
error={errors.ServiceUrl?.message}
|
||||
@@ -573,11 +573,11 @@ const CredentialAddEdit: React.FC = () => {
|
||||
{(mode === 'manual' || isEditMode) && (
|
||||
<>
|
||||
<div className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials:loginCredentials')}</h2>
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials.loginCredentials')}</h2>
|
||||
<div className="space-y-4">
|
||||
<FormInput
|
||||
id="username"
|
||||
label={t('common:username')}
|
||||
label={t('common.username')}
|
||||
value={watch('Username') ?? ''}
|
||||
onChange={(value) => setValue('Username', value)}
|
||||
error={errors.Username?.message}
|
||||
@@ -585,13 +585,13 @@ const CredentialAddEdit: React.FC = () => {
|
||||
{
|
||||
icon: 'refresh',
|
||||
onClick: generateRandomUsername,
|
||||
title: t('credentials:generateRandomUsername')
|
||||
title: t('credentials.generateRandomUsername')
|
||||
}
|
||||
]}
|
||||
/>
|
||||
<FormInput
|
||||
id="password"
|
||||
label={t('common:password')}
|
||||
label={t('common.password')}
|
||||
type="password"
|
||||
value={watch('Password') ?? ''}
|
||||
onChange={(value) => setValue('Password', value)}
|
||||
@@ -602,7 +602,7 @@ const CredentialAddEdit: React.FC = () => {
|
||||
{
|
||||
icon: 'refresh',
|
||||
onClick: generateRandomPassword,
|
||||
title: t('credentials:generateRandomPassword')
|
||||
title: t('credentials.generateRandomPassword')
|
||||
}
|
||||
]}
|
||||
/>
|
||||
@@ -611,11 +611,11 @@ const CredentialAddEdit: React.FC = () => {
|
||||
onClick={handleGenerateRandomAlias}
|
||||
className="w-full bg-primary-500 text-white py-2 px-4 rounded hover:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2"
|
||||
>
|
||||
{t('credentials:generateRandomAlias')}
|
||||
{t('credentials.generateRandomAlias')}
|
||||
</button>
|
||||
<FormInput
|
||||
id="email"
|
||||
label={t('common:email')}
|
||||
label={t('common.email')}
|
||||
value={watch('Alias.Email') ?? ''}
|
||||
onChange={(value) => setValue('Alias.Email', value)}
|
||||
error={errors.Alias?.Email?.message}
|
||||
@@ -624,40 +624,40 @@ const CredentialAddEdit: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials:alias')}</h2>
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials.alias')}</h2>
|
||||
<div className="space-y-4">
|
||||
<FormInput
|
||||
id="firstName"
|
||||
label={t('credentials:firstName')}
|
||||
label={t('credentials.firstName')}
|
||||
value={watch('Alias.FirstName') ?? ''}
|
||||
onChange={(value) => setValue('Alias.FirstName', value)}
|
||||
error={errors.Alias?.FirstName?.message}
|
||||
/>
|
||||
<FormInput
|
||||
id="lastName"
|
||||
label={t('credentials:lastName')}
|
||||
label={t('credentials.lastName')}
|
||||
value={watch('Alias.LastName') ?? ''}
|
||||
onChange={(value) => setValue('Alias.LastName', value)}
|
||||
error={errors.Alias?.LastName?.message}
|
||||
/>
|
||||
<FormInput
|
||||
id="nickName"
|
||||
label={t('credentials:nickName')}
|
||||
label={t('credentials.nickName')}
|
||||
value={watch('Alias.NickName') ?? ''}
|
||||
onChange={(value) => setValue('Alias.NickName', value)}
|
||||
error={errors.Alias?.NickName?.message}
|
||||
/>
|
||||
<FormInput
|
||||
id="gender"
|
||||
label={t('credentials:gender')}
|
||||
label={t('credentials.gender')}
|
||||
value={watch('Alias.Gender') ?? ''}
|
||||
onChange={(value) => setValue('Alias.Gender', value)}
|
||||
error={errors.Alias?.Gender?.message}
|
||||
/>
|
||||
<FormInput
|
||||
id="birthDate"
|
||||
label={t('credentials:birthDate')}
|
||||
placeholder={t('credentials:birthDatePlaceholder')}
|
||||
label={t('credentials.birthDate')}
|
||||
placeholder={t('credentials.birthDatePlaceholder')}
|
||||
value={watch('Alias.BirthDate') ?? ''}
|
||||
onChange={(value) => setValue('Alias.BirthDate', value)}
|
||||
error={errors.Alias?.BirthDate?.message}
|
||||
@@ -666,11 +666,11 @@ const CredentialAddEdit: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials:metadata')}</h2>
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">{t('credentials.metadata')}</h2>
|
||||
<div className="space-y-4">
|
||||
<FormInput
|
||||
id="notes"
|
||||
label={t('credentials:notes')}
|
||||
label={t('credentials.notes')}
|
||||
value={watch('Notes') ?? ''}
|
||||
onChange={(value) => setValue('Notes', value)}
|
||||
multiline
|
||||
|
||||
@@ -23,7 +23,7 @@ import type { Credential } from '@/utils/dist/shared/models/vault';
|
||||
* Credential details page.
|
||||
*/
|
||||
const CredentialDetails: React.FC = (): React.ReactElement => {
|
||||
const { t } = useTranslation(['common', 'credentials']);
|
||||
const { t } = useTranslation();
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const dbContext = useDb();
|
||||
@@ -76,13 +76,13 @@ const CredentialDetails: React.FC = (): React.ReactElement => {
|
||||
{!PopoutUtility.isPopup() && (
|
||||
<HeaderButton
|
||||
onClick={openInNewPopup}
|
||||
title={t('common:openInNewWindow')}
|
||||
title={t('common.openInNewWindow')}
|
||||
iconType={HeaderIconType.EXPAND}
|
||||
/>
|
||||
)}
|
||||
<HeaderButton
|
||||
onClick={handleEdit}
|
||||
title={t('credentials:editCredential')}
|
||||
title={t('credentials.editCredential')}
|
||||
iconType={HeaderIconType.EDIT}
|
||||
/>
|
||||
</div>
|
||||
@@ -97,7 +97,7 @@ const CredentialDetails: React.FC = (): React.ReactElement => {
|
||||
}, [setHeaderButtons]);
|
||||
|
||||
if (!credential) {
|
||||
return <div>{t('common:loading')}</div>;
|
||||
return <div>{t('common.loading')}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -22,7 +22,7 @@ import { useMinDurationLoading } from '@/hooks/useMinDurationLoading';
|
||||
* Credentials list page.
|
||||
*/
|
||||
const CredentialsList: React.FC = () => {
|
||||
const { t } = useTranslation('credentials');
|
||||
const { t } = useTranslation();
|
||||
const dbContext = useDb();
|
||||
const webApi = useWebApi();
|
||||
const navigate = useNavigate();
|
||||
@@ -158,14 +158,14 @@ const CredentialsList: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-gray-900 dark:text-white text-xl">{t('title')}</h2>
|
||||
<h2 className="text-gray-900 dark:text-white text-xl">{t('credentials.title')}</h2>
|
||||
<ReloadButton onClick={syncVaultAndRefresh} />
|
||||
</div>
|
||||
|
||||
{credentials.length > 0 ? (
|
||||
<input
|
||||
type="text"
|
||||
placeholder={t('searchPlaceholder')}
|
||||
placeholder={t('credentials.searchPlaceholder')}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
autoFocus
|
||||
@@ -178,13 +178,13 @@ const CredentialsList: React.FC = () => {
|
||||
{credentials.length === 0 ? (
|
||||
<div className="text-gray-500 dark:text-gray-400 space-y-2 mb-10">
|
||||
<p className="text-sm">
|
||||
{t('welcomeTitle')}
|
||||
{t('credentials.welcomeTitle')}
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
{t('welcomeDescription')}
|
||||
{t('credentials.welcomeDescription')}
|
||||
</p>
|
||||
<p className="text-sm">
|
||||
{t('manualCreationHint')}
|
||||
{t('credentials.manualCreationHint')}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -23,7 +23,7 @@ import { HeaderIconType } from '../components/Icons/HeaderIcons';
|
||||
* Email details page.
|
||||
*/
|
||||
const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
const { t } = useTranslation(['common', 'emails']);
|
||||
const { t } = useTranslation();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const dbContext = useDb();
|
||||
@@ -151,13 +151,13 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
{!PopoutUtility.isPopup() && (
|
||||
<HeaderButton
|
||||
onClick={openInNewPopup}
|
||||
title={t('common:openInNewWindow')}
|
||||
title={t('common.openInNewWindow')}
|
||||
iconType={HeaderIconType.EXPAND}
|
||||
/>
|
||||
)}
|
||||
<HeaderButton
|
||||
onClick={() => setShowDeleteModal(true)}
|
||||
title={t('emails:deleteEmail')}
|
||||
title={t('emails.deleteEmail')}
|
||||
iconType={HeaderIconType.DELETE}
|
||||
variant="danger"
|
||||
/>
|
||||
@@ -184,11 +184,11 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div className="text-red-500">{t('common:error')} {error}</div>;
|
||||
return <div className="text-red-500">{t('common.error')} {error}</div>;
|
||||
}
|
||||
|
||||
if (!email) {
|
||||
return <div className="text-gray-500">{t('emails:emailNotFound')}</div>;
|
||||
return <div className="text-gray-500">{t('emails.emailNotFound')}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -200,10 +200,10 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
setShowDeleteModal(false);
|
||||
void handleDelete();
|
||||
}}
|
||||
title={t('emails:deleteEmailTitle')}
|
||||
message={t('emails:deleteEmailConfirm')}
|
||||
confirmText={t('common:delete')}
|
||||
cancelText={t('common:cancel')}
|
||||
title={t('emails.deleteEmailTitle')}
|
||||
message={t('emails.deleteEmailConfirm')}
|
||||
confirmText={t('common.delete')}
|
||||
cancelText={t('common.cancel')}
|
||||
variant="danger"
|
||||
/>
|
||||
|
||||
@@ -214,9 +214,9 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">{email.subject}</h1>
|
||||
</div>
|
||||
<div className="space-y-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
<p>{t('emails:from')} {email.fromDisplay} ({email.fromLocal}@{email.fromDomain})</p>
|
||||
<p>{t('emails:to')} {email.toLocal}@{email.toDomain}</p>
|
||||
<p>{t('emails:date')} {new Date(email.dateSystem).toLocaleString()}</p>
|
||||
<p>{t('emails.from')} {email.fromDisplay} ({email.fromLocal}@{email.fromDomain})</p>
|
||||
<p>{t('emails.to')} {email.toLocal}@{email.toDomain}</p>
|
||||
<p>{t('emails.date')} {new Date(email.dateSystem).toLocaleString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -226,7 +226,7 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
<iframe
|
||||
srcDoc={ConversionUtility.convertAnchorTagsToOpenInNewTab(email.messageHtml)}
|
||||
className="w-full min-h-[500px] border-0"
|
||||
title={t('emails:emailContent')}
|
||||
title={t('emails.emailContent')}
|
||||
/>
|
||||
) : (
|
||||
<pre className="whitespace-pre-wrap text-gray-700 dark:text-gray-300">
|
||||
@@ -239,7 +239,7 @@ const EmailDetails: React.FC = (): React.ReactElement => {
|
||||
{email.attachments && email.attachments.length > 0 && (
|
||||
<div className="p-6 border-t border-gray-200 dark:border-gray-700">
|
||||
<h2 className="text-lg font-semibold mb-4 text-gray-900 dark:text-white">
|
||||
{t('emails:attachments')}
|
||||
{t('emails.attachments')}
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{email.attachments.map((attachment) => (
|
||||
|
||||
@@ -29,8 +29,7 @@ import { storage } from '#imports';
|
||||
* Login page
|
||||
*/
|
||||
const Login: React.FC = () => {
|
||||
const { t } = useTranslation('auth');
|
||||
const { t: tCommon } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const authContext = useAuth();
|
||||
const dbContext = useDb();
|
||||
@@ -141,7 +140,7 @@ const Login: React.FC = () => {
|
||||
|
||||
// Check if token was returned.
|
||||
if (!validationResponse.token) {
|
||||
throw new Error(t('errors.noToken'));
|
||||
throw new Error(t('auth.errors.noToken'));
|
||||
}
|
||||
|
||||
// Try to get latest vault manually providing auth token.
|
||||
@@ -149,7 +148,7 @@ const Login: React.FC = () => {
|
||||
'Authorization': `Bearer ${validationResponse.token.token}`
|
||||
} });
|
||||
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson, tCommon);
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson, t);
|
||||
if (vaultError) {
|
||||
setError(vaultError);
|
||||
hideLoading();
|
||||
@@ -174,7 +173,7 @@ const Login: React.FC = () => {
|
||||
}
|
||||
} catch (err) {
|
||||
await authContext.logout();
|
||||
setError(err instanceof Error ? err.message : t('errors.migrationError'));
|
||||
setError(err instanceof Error ? err.message : t('auth.errors.migrationError'));
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
@@ -187,9 +186,9 @@ const Login: React.FC = () => {
|
||||
} catch (err) {
|
||||
// Show API authentication errors as-is.
|
||||
if (err instanceof ApiAuthError) {
|
||||
setError(tCommon('apiErrors.' + err.message));
|
||||
setError(t('common.apiErrors.' + err.message));
|
||||
} else {
|
||||
setError(t('errors.serverError'));
|
||||
setError(t('auth.errors.serverError'));
|
||||
}
|
||||
hideLoading();
|
||||
}
|
||||
@@ -206,13 +205,13 @@ const Login: React.FC = () => {
|
||||
showLoading();
|
||||
|
||||
if (!passwordHashString || !passwordHashBase64 || !loginResponse) {
|
||||
throw new Error(t('errors.loginDataMissing'));
|
||||
throw new Error(t('auth.errors.loginDataMissing'));
|
||||
}
|
||||
|
||||
// Validate that 2FA code is a 6-digit number
|
||||
const code = twoFactorCode.trim();
|
||||
if (!/^\d{6}$/.test(code)) {
|
||||
throw new Error(t('errors.invalidCode'));
|
||||
throw new Error(t('auth.errors.invalidCode'));
|
||||
}
|
||||
|
||||
const validationResponse = await srpUtil.validateLogin2Fa(
|
||||
@@ -225,7 +224,7 @@ const Login: React.FC = () => {
|
||||
|
||||
// Check if token was returned.
|
||||
if (!validationResponse.token) {
|
||||
throw new Error(t('errors.noToken'));
|
||||
throw new Error(t('auth.errors.noToken'));
|
||||
}
|
||||
|
||||
// Try to get latest vault manually providing auth token.
|
||||
@@ -233,7 +232,7 @@ const Login: React.FC = () => {
|
||||
'Authorization': `Bearer ${validationResponse.token.token}`
|
||||
} });
|
||||
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson, tCommon);
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson, t);
|
||||
if (vaultError) {
|
||||
setError(vaultError);
|
||||
hideLoading();
|
||||
@@ -258,7 +257,7 @@ const Login: React.FC = () => {
|
||||
}
|
||||
} catch (err) {
|
||||
await authContext.logout();
|
||||
setError(err instanceof Error ? err.message : t('errors.migrationError'));
|
||||
setError(err instanceof Error ? err.message : t('auth.errors.migrationError'));
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
@@ -277,9 +276,9 @@ const Login: React.FC = () => {
|
||||
// Show API authentication errors as-is.
|
||||
console.error('2FA error:', err);
|
||||
if (err instanceof ApiAuthError) {
|
||||
setError(tCommon('apiErrors:' + err.message));
|
||||
setError(t('common.apiErrors.' + err.message));
|
||||
} else {
|
||||
setError(t('errors.serverError'));
|
||||
setError(t('auth.errors.serverError'));
|
||||
}
|
||||
hideLoading();
|
||||
}
|
||||
@@ -307,10 +306,10 @@ const Login: React.FC = () => {
|
||||
)}
|
||||
<div className="mb-6">
|
||||
<p className="text-gray-700 dark:text-gray-200 mb-4">
|
||||
{t('twoFactorTitle')}
|
||||
{t('auth.twoFactorTitle')}
|
||||
</p>
|
||||
<label className="block text-gray-700 dark:text-gray-200 text-sm font-bold mb-2" htmlFor="twoFactorCode">
|
||||
{t('authCode')}
|
||||
{t('auth.authCode')}
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 leading-tight focus:outline-none focus:shadow-outline"
|
||||
@@ -318,13 +317,13 @@ const Login: React.FC = () => {
|
||||
type="text"
|
||||
value={twoFactorCode}
|
||||
onChange={(e) => setTwoFactorCode(e.target.value)}
|
||||
placeholder={t('authCodePlaceholder')}
|
||||
placeholder={t('auth.authCodePlaceholder')}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col w-full space-y-2">
|
||||
<Button type="submit">
|
||||
{t('verify')}
|
||||
{t('auth.verify')}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -343,11 +342,11 @@ const Login: React.FC = () => {
|
||||
}}
|
||||
variant="secondary"
|
||||
>
|
||||
{t('cancel')}
|
||||
{t('auth.cancel')}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-4 text-center">
|
||||
{t('twoFactorNote')}
|
||||
{t('auth.twoFactorNote')}
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
@@ -362,18 +361,18 @@ const Login: React.FC = () => {
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
<h2 className="text-xl font-bold dark:text-gray-200">{t('loginTitle')}</h2>
|
||||
<h2 className="text-xl font-bold dark:text-gray-200">{t('auth.loginTitle')}</h2>
|
||||
<LoginServerInfo />
|
||||
<div className="mb-4">
|
||||
<label className="block text-gray-700 dark:text-gray-200 text-sm font-bold mb-2" htmlFor="username">
|
||||
{t('username')}
|
||||
{t('auth.username')}
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder={t('usernamePlaceholder')}
|
||||
placeholder={t('auth.usernamePlaceholder')}
|
||||
value={credentials.username}
|
||||
onChange={handleChange}
|
||||
required
|
||||
@@ -381,14 +380,14 @@ const Login: React.FC = () => {
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<label className="block text-gray-700 dark:text-gray-200 text-sm font-bold mb-2" htmlFor="password">
|
||||
{t('password')}
|
||||
{t('auth.password')}
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder={t('passwordPlaceholder')}
|
||||
placeholder={t('auth.passwordPlaceholder')}
|
||||
value={credentials.password}
|
||||
onChange={handleChange}
|
||||
required
|
||||
@@ -402,24 +401,24 @@ const Login: React.FC = () => {
|
||||
onChange={(e) => setRememberMe(e.target.checked)}
|
||||
className="mr-2"
|
||||
/>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-200">{t('rememberMe')}</span>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-200">{t('auth.rememberMe')}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex w-full">
|
||||
<Button type="submit">
|
||||
{t('loginButton')}
|
||||
{t('auth.loginButton')}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="text-center text-sm text-gray-600 dark:text-gray-400">
|
||||
{t('noAccount')}{' '}
|
||||
{t('auth.noAccount')}{' '}
|
||||
<a
|
||||
href={clientUrl ?? ''}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-orange-500 hover:text-orange-600 dark:text-orange-400 dark:hover:text-orange-500"
|
||||
>
|
||||
{t('createVault')}
|
||||
{t('auth.createVault')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@ type PopupSettings = {
|
||||
* Settings page component.
|
||||
*/
|
||||
const Settings: React.FC = () => {
|
||||
const { t } = useTranslation('settings');
|
||||
const { t } = useTranslation();
|
||||
const { theme, setTheme } = useTheme();
|
||||
const authContext = useAuth();
|
||||
const { setHeaderButtons } = useHeaderButtons();
|
||||
@@ -80,14 +80,14 @@ const Settings: React.FC = () => {
|
||||
<>
|
||||
<HeaderButton
|
||||
onClick={() => PopoutUtility.openInNewPopup()}
|
||||
title={t('openInNewWindow')}
|
||||
title={t('settings.openInNewWindow')}
|
||||
iconType={HeaderIconType.EXPAND}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<HeaderButton
|
||||
onClick={openClientTab}
|
||||
title={t('openWebApp')}
|
||||
title={t('settings.openWebApp')}
|
||||
iconType={HeaderIconType.EXTERNAL_LINK}
|
||||
/>
|
||||
</div>
|
||||
@@ -258,7 +258,7 @@ const Settings: React.FC = () => {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-gray-900 dark:text-white text-xl">{t('title')}</h2>
|
||||
<h2 className="text-gray-900 dark:text-white text-xl">{t('settings.title')}</h2>
|
||||
</div>
|
||||
|
||||
{/* User Menu Section */}
|
||||
@@ -279,7 +279,7 @@ const Settings: React.FC = () => {
|
||||
{authContext.username}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
{t('loggedIn')}
|
||||
{t('settings.loggedIn')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -287,7 +287,7 @@ const Settings: React.FC = () => {
|
||||
onClick={handleLogout}
|
||||
className="px-4 py-2 text-sm font-medium text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
|
||||
>
|
||||
{t('logout')}
|
||||
{t('settings.logout')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -296,14 +296,14 @@ const Settings: React.FC = () => {
|
||||
|
||||
{/* Global Settings Section */}
|
||||
<section>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('globalSettings')}</h3>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('settings.globalSettings')}</h3>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('autofillPopup')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('settings.autofillPopup')}</p>
|
||||
<p className={`text-sm mt-1 ${settings.isGloballyEnabled ? 'text-gray-600 dark:text-gray-400' : 'text-red-600 dark:text-red-400'}`}>
|
||||
{settings.isGloballyEnabled ? t('activeOnAllSites') : t('disabledOnAllSites')}
|
||||
{settings.isGloballyEnabled ? t('settings.activeOnAllSites') : t('settings.disabledOnAllSites')}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -314,15 +314,15 @@ const Settings: React.FC = () => {
|
||||
: 'bg-red-500 hover:bg-red-600 text-white'
|
||||
}`}
|
||||
>
|
||||
{settings.isGloballyEnabled ? t('enabled') : t('disabled')}
|
||||
{settings.isGloballyEnabled ? t('settings.enabled') : t('settings.disabled')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('rightClickContextMenu')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('settings.rightClickContextMenu')}</p>
|
||||
<p className={`text-sm mt-1 ${settings.isContextMenuEnabled ? 'text-gray-600 dark:text-gray-400' : 'text-red-600 dark:text-red-400'}`}>
|
||||
{settings.isContextMenuEnabled ? t('enabled') : t('disabled')}
|
||||
{settings.isContextMenuEnabled ? t('settings.enabled') : t('settings.disabled')}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
@@ -343,18 +343,18 @@ const Settings: React.FC = () => {
|
||||
{/* Site-Specific Settings Section */}
|
||||
{settings.isGloballyEnabled && (
|
||||
<section>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('siteSpecificSettings')}</h3>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('settings.siteSpecificSettings')}</h3>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('autofillPopupOn')}{settings.currentUrl}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('settings.autofillPopupOn')}{settings.currentUrl}</p>
|
||||
<p className={`text-sm mt-1 ${settings.isEnabled ? 'text-gray-600 dark:text-gray-400' : 'text-red-600 dark:text-red-400'}`}>
|
||||
{settings.isEnabled ? t('enabledForThisSite') : t('disabledForThisSite')}
|
||||
{settings.isEnabled ? t('settings.enabledForThisSite') : t('settings.disabledForThisSite')}
|
||||
</p>
|
||||
{!settings.isEnabled && settings.temporaryDisabledUrls[settings.currentUrl] && (
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
{t('temporarilyDisabledUntil')}{new Date(settings.temporaryDisabledUrls[settings.currentUrl]).toLocaleTimeString()}
|
||||
{t('settings.temporarilyDisabledUntil')}{new Date(settings.temporaryDisabledUrls[settings.currentUrl]).toLocaleTimeString()}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -367,7 +367,7 @@ const Settings: React.FC = () => {
|
||||
: 'bg-red-500 hover:bg-red-600 text-white'
|
||||
}`}
|
||||
>
|
||||
{settings.isEnabled ? t('enabled') : t('disabled')}
|
||||
{settings.isEnabled ? t('settings.enabled') : t('settings.disabled')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -377,7 +377,7 @@ const Settings: React.FC = () => {
|
||||
onClick={resetSettings}
|
||||
className="w-full px-4 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-md text-gray-700 dark:text-gray-300 transition-colors text-sm"
|
||||
>
|
||||
{t('resetAllSiteSettings')}
|
||||
{t('settings.resetAllSiteSettings')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -387,17 +387,17 @@ const Settings: React.FC = () => {
|
||||
|
||||
{/* Appearance Settings Section */}
|
||||
<section>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('appearance')}</h3>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('settings.appearance')}</h3>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-4">
|
||||
<div className="mb-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white mb-3">{t('language')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white mb-3">{t('settings.language')}</p>
|
||||
<LanguageSwitcher variant="dropdown" size="sm" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white mb-2">{t('theme')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white mb-2">{t('settings.theme')}</p>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
@@ -408,7 +408,7 @@ const Settings: React.FC = () => {
|
||||
onChange={() => setThemePreference('system')}
|
||||
className="mr-2"
|
||||
/>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('useDefault')}</span>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('settings.useDefault')}</span>
|
||||
</label>
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
@@ -419,7 +419,7 @@ const Settings: React.FC = () => {
|
||||
onChange={() => setThemePreference('light')}
|
||||
className="mr-2"
|
||||
/>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('light')}</span>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('settings.light')}</span>
|
||||
</label>
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
@@ -430,7 +430,7 @@ const Settings: React.FC = () => {
|
||||
onChange={() => setThemePreference('dark')}
|
||||
className="mr-2"
|
||||
/>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('dark')}</span>
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">{t('settings.dark')}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -441,18 +441,18 @@ const Settings: React.FC = () => {
|
||||
{/* Keyboard Shortcuts Section */}
|
||||
{import.meta.env.CHROME && (
|
||||
<section>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('keyboardShortcuts')}</h3>
|
||||
<h3 className="text-md font-semibold text-gray-900 dark:text-white mb-3">{t('settings.keyboardShortcuts')}</h3>
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
|
||||
<div className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('configureKeyboardShortcuts')}</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{t('settings.configureKeyboardShortcuts')}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={openKeyboardShortcuts}
|
||||
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-md transition-colors"
|
||||
>
|
||||
{t('configure')}
|
||||
{t('settings.configure')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -461,7 +461,7 @@ const Settings: React.FC = () => {
|
||||
)}
|
||||
|
||||
<div className="text-center text-gray-400 dark:text-gray-600">
|
||||
{t('versionPrefix')}{AppInfo.VERSION} ({getDisplayUrl()})
|
||||
{t('settings.versionPrefix')}{AppInfo.VERSION} ({getDisplayUrl()})
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -25,8 +25,7 @@ import { storage } from '#imports';
|
||||
* Unlock page
|
||||
*/
|
||||
const Unlock: React.FC = () => {
|
||||
const { t } = useTranslation('auth');
|
||||
const { t: tc } = useTranslation('common');
|
||||
const { t } = useTranslation();
|
||||
const authContext = useAuth();
|
||||
const dbContext = useDb();
|
||||
const navigate = useNavigate();
|
||||
@@ -47,21 +46,21 @@ const Unlock: React.FC = () => {
|
||||
const statusResponse = await webApi.getStatus();
|
||||
const statusError = webApi.validateStatusResponse(statusResponse);
|
||||
if (statusError !== null) {
|
||||
await webApi.logout(tc(statusError));
|
||||
await webApi.logout(t('common.apiErrors.' + statusError));
|
||||
navigate('/logout');
|
||||
}
|
||||
setIsInitialLoading(false);
|
||||
};
|
||||
|
||||
checkStatus();
|
||||
}, [webApi, authContext, setIsInitialLoading, navigate, tc]);
|
||||
}, [webApi, authContext, setIsInitialLoading, navigate, t]);
|
||||
|
||||
// Set header buttons on mount and clear on unmount
|
||||
useEffect((): (() => void) => {
|
||||
const headerButtonsJSX = !PopoutUtility.isPopup() ? (
|
||||
<HeaderButton
|
||||
onClick={() => PopoutUtility.openInNewPopup()}
|
||||
title={t('common:openInNewWindow', 'Open in new window')}
|
||||
title={t('common.openInNewWindow')}
|
||||
iconType={HeaderIconType.EXPAND}
|
||||
/>
|
||||
) : null;
|
||||
@@ -96,9 +95,9 @@ const Unlock: React.FC = () => {
|
||||
// Make API call to get latest vault
|
||||
const vaultResponseJson = await webApi.get<VaultResponse>('Vault');
|
||||
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson);
|
||||
const vaultError = webApi.validateVaultResponse(vaultResponseJson, t);
|
||||
if (vaultError) {
|
||||
setError(vaultError);
|
||||
setError(t('common.apiErrors.' + vaultError));
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
@@ -115,7 +114,7 @@ const Unlock: React.FC = () => {
|
||||
// Redirect to reinitialize page
|
||||
navigate('/reinitialize', { replace: true });
|
||||
} catch (err) {
|
||||
setError(t('errors.wrongPassword'));
|
||||
setError(t('auth.errors.wrongPassword'));
|
||||
console.error('Unlock error:', err);
|
||||
} finally {
|
||||
hideLoading();
|
||||
@@ -146,14 +145,14 @@ const Unlock: React.FC = () => {
|
||||
{authContext.username}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
{t('loggedIn')}
|
||||
{t('auth.loggedIn')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Instruction Title */}
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-4">
|
||||
{t('unlockTitle')}
|
||||
{t('auth.unlockTitle')}
|
||||
</h2>
|
||||
|
||||
{error && (
|
||||
@@ -164,7 +163,7 @@ const Unlock: React.FC = () => {
|
||||
|
||||
<div className="mb-2">
|
||||
<label className="block text-gray-700 dark:text-gray-200 text-sm font-bold mb-2" htmlFor="password">
|
||||
{t('masterPassword')}
|
||||
{t('auth.masterPassword')}
|
||||
</label>
|
||||
<input
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 mb-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||
@@ -172,17 +171,17 @@ const Unlock: React.FC = () => {
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder={t('passwordPlaceholder')}
|
||||
placeholder={t('auth.passwordPlaceholder')}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit">
|
||||
{t('unlockVault')}
|
||||
{t('auth.unlockVault')}
|
||||
</Button>
|
||||
|
||||
<div className="text-sm font-medium text-gray-500 dark:text-gray-200 mt-6">
|
||||
{t('switchAccounts')} <button onClick={handleLogout} className="text-primary-700 hover:underline dark:text-primary-500">{t('logout')}</button>
|
||||
{t('auth.switchAccounts')} <button onClick={handleLogout} className="text-primary-700 hover:underline dark:text-primary-500">{t('auth.logout')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
*/
|
||||
const UnlockSuccess: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('auth');
|
||||
const { t } = useTranslation();
|
||||
|
||||
/**
|
||||
* Handle browsing vault contents - navigate to credentials page and reset mode parameter
|
||||
@@ -31,23 +31,23 @@ const UnlockSuccess: React.FC = () => {
|
||||
</svg>
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold mb-4 text-gray-900 dark:text-white">
|
||||
{t('unlockSuccessTitle')}
|
||||
{t('auth.unlockSuccessTitle')}
|
||||
</h2>
|
||||
<p className="mb-6 text-gray-600 dark:text-gray-400">
|
||||
{t('unlockSuccessDescription')}
|
||||
{t('auth.unlockSuccessDescription')}
|
||||
</p>
|
||||
<div className="space-y-3 w-full">
|
||||
<button
|
||||
onClick={() => window.close()}
|
||||
className="w-full px-4 py-2 text-white bg-primary-600 rounded hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2"
|
||||
>
|
||||
{t('closePopup')}
|
||||
{t('auth.closePopup')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleBrowseVaultContents}
|
||||
className="w-full px-4 py-2 text-gray-700 bg-gray-100 rounded hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
|
||||
>
|
||||
{t('browseVault')}
|
||||
{t('auth.browseVault')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
316
apps/browser-extension/src/locales/de.json
Normal file
316
apps/browser-extension/src/locales/de.json
Normal file
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Credentials",
|
||||
"emails": "Emails",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"connectingTo": "Connecting to",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation..."
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailInUse": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"emailSyncError": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version "
|
||||
}
|
||||
316
apps/browser-extension/src/locales/en.json
Normal file
316
apps/browser-extension/src/locales/en.json
Normal file
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Credentials",
|
||||
"emails": "Emails",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
316
apps/browser-extension/src/locales/es.json
Normal file
316
apps/browser-extension/src/locales/es.json
Normal file
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Credentials",
|
||||
"emails": "Emails",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"connectingTo": "Connecting to",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation..."
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailInUse": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"emailSyncError": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version "
|
||||
}
|
||||
316
apps/browser-extension/src/locales/fr.json
Normal file
316
apps/browser-extension/src/locales/fr.json
Normal file
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Credentials",
|
||||
"emails": "Emails",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"connectingTo": "Connecting to",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation..."
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailInUse": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"emailSyncError": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version "
|
||||
}
|
||||
307
apps/browser-extension/src/locales/nl.json
Normal file
307
apps/browser-extension/src/locales/nl.json
Normal file
@@ -0,0 +1,307 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Inloggen bij AliasVault",
|
||||
"username": "Gebruikersnaam of e-mail",
|
||||
"usernamePlaceholder": "naam / naam@bedrijf.com",
|
||||
"password": "Wachtwoord",
|
||||
"passwordPlaceholder": "Voer je wachtwoord in",
|
||||
"rememberMe": "Onthoud mij",
|
||||
"loginButton": "Inloggen",
|
||||
"noAccount": "Nog geen account?",
|
||||
"createVault": "Nieuwe vault aanmaken",
|
||||
"twoFactorTitle": "Voer de authenticatiecode van je authenticator-app in.",
|
||||
"authCode": "Authenticatiecode",
|
||||
"authCodePlaceholder": "Voer 6-cijferige code in",
|
||||
"verify": "Verifiëren",
|
||||
"cancel": "Annuleren",
|
||||
"twoFactorNote": "Opmerking: als je geen toegang hebt tot je authenticator, kunt je je 2FA resetten door met een in te loggen via de website.",
|
||||
"masterPassword": "Hoofdwachtwoord",
|
||||
"unlockVault": "Vault ontgrendelen",
|
||||
"unlockTitle": "Ontgrendel je vault",
|
||||
"unlockDescription": "Voer je hoofdwachtwoord in om je vault te ontgrendelen.",
|
||||
"logout": "Uitloggen",
|
||||
"logoutConfirm": "Weet je zeker dat je wilt uitloggen?",
|
||||
"sessionExpired": "Je sessie is verlopen. Log opnieuw in.",
|
||||
"unlockSuccess": "Vault succesvol ontgrendeld!",
|
||||
"unlockSuccessTitle": "Je vault is succesvol ontgrendeld",
|
||||
"unlockSuccessDescription": "Je kunt nu automatisch invullen gebruiken in inlogformulieren in je browser.",
|
||||
"closePopup": "Sluit deze popup",
|
||||
"browseVault": "Bekijk vault-inhoud",
|
||||
"connectingTo": "Verbinden met",
|
||||
"loggedIn": "Ingelogd",
|
||||
"errors": {
|
||||
"invalidCode": "Voer een geldige 6-cijferige code in.",
|
||||
"serverError": "Kon de AliasVault server niet bereiken. Probeer het later opnieuw of neem contact op met support als het probleem aanhoudt.",
|
||||
"noToken": "Inloggen mislukt -- geen token ontvangen",
|
||||
"migrationError": "Er is een fout opgetreden bij het controleren op updates.",
|
||||
"wrongPassword": "Onjuist wachtwoord. Probeer het opnieuw.",
|
||||
"accountLocked": "Account tijdelijk vergrendeld vanwege te veel mislukte pogingen.",
|
||||
"networkError": "Netwerkfout. Controleer de verbinding en probeer het opnieuw.",
|
||||
"loginDataMissing": "Loginsessie verlopen. Probeer het opnieuw."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Inloggegevens",
|
||||
"emails": "E-mails",
|
||||
"settings": "Instellingen"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Laden...",
|
||||
"error": "Fout",
|
||||
"success": "Succes",
|
||||
"cancel": "Annuleren",
|
||||
"delete": "Verwijderen",
|
||||
"close": "Sluiten",
|
||||
"copied": "Gekopieerd!",
|
||||
"openInNewWindow": "Openen in nieuw venster",
|
||||
"language": "Taal",
|
||||
"enabled": "Ingeschakeld",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"showPassword": "Wachtwoord tonen",
|
||||
"hidePassword": "Wachtwoord verbergen",
|
||||
"copyToClipboard": "Naar klembord kopiëren",
|
||||
"loadingEmails": "E-mails laden...",
|
||||
"loadingTotpCodes": "TOTP-codes laden...",
|
||||
"settings": "Instellingen",
|
||||
"recentEmails": "Recente e-mails",
|
||||
"loginCredentials": "Inloggegevens",
|
||||
"twoFactorAuthentication": "Twee-factor authenticatie",
|
||||
"alias": "Alias",
|
||||
"notes": "Notities",
|
||||
"fullName": "Volledige Naam",
|
||||
"firstName": "Voornaam",
|
||||
"lastName": "Achternaam",
|
||||
"birthDate": "Geboortedatum",
|
||||
"nickname": "Bijnaam",
|
||||
"email": "E-mail",
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"syncingVault": "Vault synchroniseren",
|
||||
"savingChangesToVault": "Wijzigingen opslaan in vault",
|
||||
"uploadingVaultToServer": "Vault uploaden naar server",
|
||||
"checkingVaultUpdates": "Controleren op vault updates",
|
||||
"syncingUpdatedVault": "Bijgewerkte vault synchroniseren",
|
||||
"executingOperation": "Actie uitvoeren...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Uw vault moet worden bijgewerkt. Log in op de AliasVault website en volg de stappen.",
|
||||
"VaultOutdated": "Uw vault is verouderd. Log in op de AliasVault website en volg de stappen.",
|
||||
"NoVaultFound": "Uw account heeft nog geen vault. Voltooi eerst de tutorial in de AliasVault webclient voordat u de browserextensie gebruikt.",
|
||||
"serverNotAvailable": "De AliasVault server is niet beschikbaar. Probeer het later opnieuw of neem contact op met de ondersteuning als het probleem aanhoudt.",
|
||||
"clientVersionNotSupported": "Deze versie van de AliasVault browserextensie wordt niet meer ondersteund door de server. Update uw browserextensie naar de nieuwste versie.",
|
||||
"serverVersionNotSupported": "De AliasVault server moet worden bijgewerkt naar een nieuwere versie om deze browserextensie te kunnen gebruiken. Neem contact op met de ondersteuning als u hulp nodig hebt.",
|
||||
"unknownError": "Er is een onbekende fout opgetreden",
|
||||
"failedToStoreVault": "Vault opslaan mislukt",
|
||||
"vaultNotAvailable": "Vault niet beschikbaar",
|
||||
"failedToGetVault": "Vault ophalen mislukt",
|
||||
"vaultIsLocked": "Vault is vergrendeld",
|
||||
"failedToGetCredentials": "Inloggegevens ophalen mislukt",
|
||||
"failedToCreateIdentity": "Identiteit aanmaken mislukt",
|
||||
"failedToGetDefaultEmailDomain": "Standaard e-maildomein ophalen mislukt",
|
||||
"failedToGetDefaultIdentitySettings": "Standaard identiteitsinstellingen ophalen mislukt",
|
||||
"failedToGetPasswordSettings": "Wachtwoordinstellingen ophalen mislukt",
|
||||
"failedToUploadVault": "Vault uploaden mislukt",
|
||||
"noDerivedKeyAvailable": "Geen afgeleide sleutel beschikbaar voor versleuteling",
|
||||
"failedToUploadVaultToServer": "Nieuwe vault uploaden naar server mislukt",
|
||||
"noVaultOrDerivedKeyFound": "Geen vault of afgeleide sleutel gevonden"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "Er is een onbekende fout opgetreden. Probeer het opnieuw.",
|
||||
"ACCOUNT_LOCKED": "Account tijdelijk vergrendeld vanwege te veel mislukte pogingen. Probeer het later opnieuw.",
|
||||
"ACCOUNT_BLOCKED": "Uw account is uitgeschakeld. Als u denkt dat dit een vergissing is, neem dan contact op met de ondersteuning.",
|
||||
"USER_NOT_FOUND": "Gebruikersnaam of wachtwoord is onjuist. Probeer het opnieuw.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Ongeldige authenticatiecode. Probeer het opnieuw.",
|
||||
"INVALID_RECOVERY_CODE": "Ongeldige herstelcode. Probeer het opnieuw.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Vernieuwingstoken is vereist.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "Gebruiker niet gevonden in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "Gebruiker niet gevonden in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Ongeldig vernieuwingstoken.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Vernieuwingstoken succesvol ingetrokken.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "Registratie van nieuwe accounts is momenteel uitgeschakeld op deze server. Neem contact op met de beheerder.",
|
||||
"USERNAME_REQUIRED": "Gebruikersnaam is vereist.",
|
||||
"USERNAME_ALREADY_IN_USE": "Gebruikersnaam is al in gebruik.",
|
||||
"USERNAME_AVAILABLE": "Gebruikersnaam is beschikbaar.",
|
||||
"USERNAME_MISMATCH": "Gebruikersnaam komt niet overeen met de huidige gebruiker.",
|
||||
"PASSWORD_MISMATCH": "Het opgegeven wachtwoord komt niet overeen met uw huidige wachtwoord.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account succesvol verwijderd.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Gebruikersnaam mag niet leeg zijn of alleen uit spaties bestaan.",
|
||||
"USERNAME_TOO_SHORT": "Gebruikersnaam te kort: moet minimaal 3 tekens lang zijn.",
|
||||
"USERNAME_TOO_LONG": "Gebruikersnaam te lang: mag niet langer zijn dan 40 tekens.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Gebruikersnaam 'admin' is niet toegestaan.",
|
||||
"USERNAME_INVALID_EMAIL": "Ongeldig e-mailadres.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Gebruikersnaam is ongeldig, mag alleen letters of cijfers bevatten.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Uw kluis is niet up-to-date. Synchroniseer uw kluis en probeer het opnieuw.",
|
||||
"INTERNAL_SERVER_ERROR": "Interne serverfout.",
|
||||
"VAULT_ERROR": "De lokale kluis is niet up-to-date. Synchroniseer uw kluis door de pagina te vernieuwen en probeer het opnieuw."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "Nieuw",
|
||||
"cancel": "Annuleren",
|
||||
"search": "Zoeken",
|
||||
"vaultLocked": "AliasVault is vergrendeld.",
|
||||
"creatingNewAlias": "Nieuwe alias aanmaken...",
|
||||
"noMatchesFound": "Geen resultaten gevonden",
|
||||
"searchVault": "Kluis doorzoeken...",
|
||||
"serviceName": "Servicenaam",
|
||||
"email": "E-mail",
|
||||
"username": "Gebruikersnaam",
|
||||
"generatedPassword": "Gegenereerd wachtwoord",
|
||||
"enterServiceName": "Voer servicenaam in",
|
||||
"enterEmailAddress": "Voer e-mailadres in",
|
||||
"enterUsername": "Voer gebruikersnaam in",
|
||||
"hideFor1Hour": "Verberg voor 1 uur (huidige site)",
|
||||
"hidePermanently": "Permanent verbergen (huidige site)",
|
||||
"createRandomAlias": "Willekeurige alias aanmaken",
|
||||
"createUsernamePassword": "Gebruikersnaam/wachtwoord aanmaken",
|
||||
"randomAlias": "Willekeurige alias",
|
||||
"usernamePassword": "Gebruikersnaam/wachtwoord",
|
||||
"createAndSaveAlias": "Alias aanmaken en opslaan",
|
||||
"createAndSaveCredential": "Inloggegevens aanmaken en opslaan",
|
||||
"randomIdentityDescription": "Genereer een willekeurige identiteit met een willekeurig e-mailadres toegankelijk in AliasVault.",
|
||||
"manualCredentialDescription": "Specificeer je eigen e-mailadres en gebruikersnaam.",
|
||||
"failedToCreateIdentity": "Identiteit aanmaken mislukt. Probeer opnieuw.",
|
||||
"enterEmailAndOrUsername": "Voer e-mail en/of gebruikersnaam in",
|
||||
"autofillWithAliasVault": "Autofill met AliasVault",
|
||||
"generateRandomPassword": "Willekeurig wachtwoord genereren (kopiëren naar klembord)",
|
||||
"passwordCopiedToClipboard": "Wachtwoord gekopieerd naar klembord"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Inloggegevens toevoegen",
|
||||
"editCredential": "Credential bewerken",
|
||||
"deleteCredential": "Credential verwijderen",
|
||||
"credentialDetails": "Credential details",
|
||||
"serviceName": "Naam dienst",
|
||||
"serviceNamePlaceholder": "bijv. Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://voorbeeld.nl",
|
||||
"username": "Gebruikersnaam",
|
||||
"usernamePlaceholder": "Voer gebruikersnaam in",
|
||||
"password": "Wachtwoord",
|
||||
"passwordPlaceholder": "Voer wachtwoord in",
|
||||
"generatePassword": "Wachtwoord genereren",
|
||||
"copyPassword": "Wachtwoord kopiëren",
|
||||
"showPassword": "Wachtwoord tonen",
|
||||
"hidePassword": "Wachtwoord verbergen",
|
||||
"notes": "Notities",
|
||||
"notesPlaceholder": "Aanvullende notities...",
|
||||
"totp": "Twee-factor-authenticatie",
|
||||
"totpCode": "TOTP-code",
|
||||
"copyTotp": "Kopiëren",
|
||||
"totpSecret": "TOTP-sleutel",
|
||||
"totpSecretPlaceholder": "Voer TOTP-secret key in",
|
||||
"noCredentials": "Geen credentials gevonden",
|
||||
"noCredentialsDescription": "Voeg je eerste credentials toe om te beginnen",
|
||||
"searchCredentials": "Zoek credentials...",
|
||||
"searchPlaceholder": "Credentials zoeken...",
|
||||
"welcomeTitle": "Welkom bij AliasVault!",
|
||||
"welcomeDescription": "Om de AliasVault browser extensie te gebruiken: navigeer naar een website en gebruik de AliasVault autofill popup om nieuwe credentials aan te maken.",
|
||||
"manualCreationHint": "Als je handmatig identiteiten wilt aanmaken, open dan de volledige AliasVault app via het uitklapicoon in de rechterbovenhoek.",
|
||||
"lastUsed": "Laatst gebruikt",
|
||||
"createdAt": "Aangemaakt",
|
||||
"updatedAt": "Laatst bijgewerkt",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Formulier invullen",
|
||||
"copyUsername": "Gebruikersnaam kopiëren",
|
||||
"openWebsite": "Website openen",
|
||||
"favorite": "Favoriet",
|
||||
"unfavorite": "Uit favorieten verwijderen",
|
||||
"deleteConfirm": "Weet u zeker dat u deze credential wilt verwijderen?",
|
||||
"deleteSuccess": "Credential succesvol verwijderd",
|
||||
"saveSuccess": "Credential succesvol opgeslagen",
|
||||
"copySuccess": "Gekopieerd naar klembord",
|
||||
"tags": "Labels",
|
||||
"addTag": "Label toevoegen",
|
||||
"removeTag": "Label verwijderen",
|
||||
"folder": "Map",
|
||||
"selectFolder": "Map selecteren",
|
||||
"createFolder": "Map aanmaken",
|
||||
"saveCredential": "Credential opslaan",
|
||||
"deleteCredentialTitle": "Credential verwijderen",
|
||||
"deleteCredentialConfirm": "Weet je zeker dat je deze credential wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.",
|
||||
"randomAlias": "Willekeurige alias",
|
||||
"manual": "Handmatig",
|
||||
"service": "Naam van dienst",
|
||||
"serviceUrl": "URL",
|
||||
"loginCredentials": "Inloggegevens",
|
||||
"generateRandomUsername": "Gebruikersnaam genereren",
|
||||
"generateRandomPassword": "Wachtwoord genereren",
|
||||
"generateRandomAlias": "Alias genereren",
|
||||
"alias": "Alias",
|
||||
"firstName": "Voornaam",
|
||||
"lastName": "Achternaam",
|
||||
"nickName": "Bijnaam",
|
||||
"gender": "Geslacht",
|
||||
"birthDate": "Geboortedatum",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Servicenaam is verplicht",
|
||||
"invalidUrl": "Voer een geldige URL in",
|
||||
"saveError": "Credential opslaan mislukt",
|
||||
"loadError": "Credential laden mislukt",
|
||||
"deleteError": "Credential verwijderen mislukt",
|
||||
"copyError": "Kopiëren naar klembord mislukt"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "E-mail details",
|
||||
"deleteEmailTitle": "E-mail Verwijderen",
|
||||
"deleteEmailConfirm": "Weet u zeker dat u deze e-mail definitief wilt verwijderen?",
|
||||
"from": "Van",
|
||||
"to": "Naar",
|
||||
"date": "Datum",
|
||||
"emailContent": "E-mailinhoud",
|
||||
"attachments": "Bijlagen",
|
||||
"emailNotFound": "E-mail niet gevonden",
|
||||
"noEmails": "Geen e-mails gevonden",
|
||||
"errors": {
|
||||
"emailLoadError": "Er is een fout opgetreden bij het laden van e-mails. Probeer het later opnieuw.",
|
||||
"emailUnexpectedError": "Er is een onverwachte fout opgetreden bij het laden van e-mails. Probeer het later opnieuw."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "Het huidige gekozen e-mailadres is al in gebruik. Wijzig het e-mailadres door deze credential te bewerken.",
|
||||
"CLAIM_DOES_NOT_EXIST": "Er is een fout opgetreden bij het laden van e-mails. Probeer de credential te bewerken en op te slaan om de database te synchroniseren, en probeer het opnieuw."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Instellingen",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Taal",
|
||||
"autofillEnabled": "Autofill",
|
||||
"version": "Versie",
|
||||
"openInNewWindow": "Openen in nieuw venster",
|
||||
"openWebApp": "Web-app openen",
|
||||
"loggedIn": "Ingelogd",
|
||||
"logout": "Uitloggen",
|
||||
"globalSettings": "Globale Instellingen",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Actief voor alle sites (tenzij hieronder uitgeschakeld)",
|
||||
"disabledOnAllSites": "Uitgeschakeld op alle sites",
|
||||
"enabled": "Ingeschakeld",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"rightClickContextMenu": "Rechts-klik contextmenu",
|
||||
"siteSpecificSettings": "Site-specifieke Instellingen",
|
||||
"autofillPopupOn": "Autofill popup op: ",
|
||||
"enabledForThisSite": "Ingeschakeld voor deze site",
|
||||
"disabledForThisSite": "Uitgeschakeld voor deze site",
|
||||
"temporarilyDisabledUntil": "Tijdelijk uitgeschakeld tot ",
|
||||
"resetAllSiteSettings": "Alle site-specifieke instellingen resetten",
|
||||
"appearance": "Uiterlijk",
|
||||
"theme": "Thema",
|
||||
"useDefault": "Standaard gebruiken",
|
||||
"light": "Licht",
|
||||
"dark": "Donker",
|
||||
"keyboardShortcuts": "Snelkoppelingen",
|
||||
"configureKeyboardShortcuts": "Snelkoppelingen configureren",
|
||||
"configure": "Configureren",
|
||||
"versionPrefix": "Versie ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is vereist",
|
||||
"apiUrlInvalid": "Voer een geldige API URL in",
|
||||
"clientUrlRequired": "Client URL is vereist",
|
||||
"clientUrlInvalid": "Voer een geldige client URL in"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Inloggen bij AliasVault",
|
||||
"username": "Gebruikersnaam of e-mail",
|
||||
"usernamePlaceholder": "naam / naam@bedrijf.com",
|
||||
"password": "Wachtwoord",
|
||||
"passwordPlaceholder": "Voer je wachtwoord in",
|
||||
"rememberMe": "Onthoud mij",
|
||||
"loginButton": "Inloggen",
|
||||
"noAccount": "Nog geen account?",
|
||||
"createVault": "Nieuwe vault aanmaken",
|
||||
"twoFactorTitle": "Voer de authenticatiecode van je authenticator-app in.",
|
||||
"authCode": "Authenticatiecode",
|
||||
"authCodePlaceholder": "Voer 6-cijferige code in",
|
||||
"verify": "Verifiëren",
|
||||
"cancel": "Annuleren",
|
||||
"twoFactorNote": "Opmerking: als je geen toegang hebt tot je authenticator, kunt je je 2FA resetten door met een in te loggen via de website.",
|
||||
"masterPassword": "Hoofdwachtwoord",
|
||||
"unlockVault": "Vault ontgrendelen",
|
||||
"unlockTitle": "Ontgrendel je vault",
|
||||
"unlockDescription": "Voer je hoofdwachtwoord in om je vault te ontgrendelen.",
|
||||
"logout": "Uitloggen",
|
||||
"logoutConfirm": "Weet je zeker dat je wilt uitloggen?",
|
||||
"sessionExpired": "Je sessie is verlopen. Log opnieuw in.",
|
||||
"unlockSuccess": "Vault succesvol ontgrendeld!",
|
||||
"unlockSuccessTitle": "Je vault is succesvol ontgrendeld",
|
||||
"unlockSuccessDescription": "Je kunt nu automatisch invullen gebruiken in inlogformulieren in je browser.",
|
||||
"closePopup": "Sluit deze popup",
|
||||
"browseVault": "Bekijk vault-inhoud",
|
||||
"connectingTo": "Verbinden met",
|
||||
"loggedIn": "Ingelogd",
|
||||
"errors": {
|
||||
"invalidCode": "Voer een geldige 6-cijferige code in.",
|
||||
"serverError": "Kon de AliasVault server niet bereiken. Probeer het later opnieuw of neem contact op met support als het probleem aanhoudt.",
|
||||
"noToken": "Inloggen mislukt -- geen token ontvangen",
|
||||
"migrationError": "Er is een fout opgetreden bij het controleren op updates.",
|
||||
"wrongPassword": "Onjuist wachtwoord. Probeer het opnieuw.",
|
||||
"accountLocked": "Account tijdelijk vergrendeld vanwege te veel mislukte pogingen.",
|
||||
"networkError": "Netwerkfout. Controleer de verbinding en probeer het opnieuw.",
|
||||
"loginDataMissing": "Loginsessie verlopen. Probeer het opnieuw."
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Laden...",
|
||||
"error": "Fout",
|
||||
"success": "Succes",
|
||||
"cancel": "Annuleren",
|
||||
"delete": "Verwijderen",
|
||||
"close": "Sluiten",
|
||||
"copied": "Gekopieerd!",
|
||||
"openInNewWindow": "Openen in nieuw venster",
|
||||
"language": "Taal",
|
||||
"enabled": "Ingeschakeld",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"showPassword": "Wachtwoord tonen",
|
||||
"hidePassword": "Wachtwoord verbergen",
|
||||
"copyToClipboard": "Naar klembord kopiëren",
|
||||
"loadingEmails": "E-mails laden...",
|
||||
"loadingTotpCodes": "TOTP-codes laden...",
|
||||
"settings": "Instellingen",
|
||||
"recentEmails": "Recente e-mails",
|
||||
"loginCredentials": "Inloggegevens",
|
||||
"twoFactorAuthentication": "Twee-factor authenticatie",
|
||||
"alias": "Alias",
|
||||
"notes": "Notities",
|
||||
"fullName": "Volledige Naam",
|
||||
"firstName": "Voornaam",
|
||||
"lastName": "Achternaam",
|
||||
"birthDate": "Geboortedatum",
|
||||
"nickname": "Bijnaam",
|
||||
"email": "E-mail",
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"syncingVault": "Vault synchroniseren",
|
||||
"savingChangesToVault": "Wijzigingen opslaan in vault",
|
||||
"uploadingVaultToServer": "Vault uploaden naar server",
|
||||
"checkingVaultUpdates": "Controleren op vault updates",
|
||||
"syncingUpdatedVault": "Bijgewerkte vault synchroniseren",
|
||||
"executingOperation": "Actie uitvoeren...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Uw vault moet worden bijgewerkt. Log in op de AliasVault website en volg de stappen.",
|
||||
"VaultOutdated": "Uw vault is verouderd. Log in op de AliasVault website en volg de stappen.",
|
||||
"NoVaultFound": "Uw account heeft nog geen vault. Voltooi eerst de tutorial in de AliasVault webclient voordat u de browserextensie gebruikt.",
|
||||
"serverNotAvailable": "De AliasVault server is niet beschikbaar. Probeer het later opnieuw of neem contact op met de ondersteuning als het probleem aanhoudt.",
|
||||
"clientVersionNotSupported": "Deze versie van de AliasVault browserextensie wordt niet meer ondersteund door de server. Update uw browserextensie naar de nieuwste versie.",
|
||||
"serverVersionNotSupported": "De AliasVault server moet worden bijgewerkt naar een nieuwere versie om deze browserextensie te kunnen gebruiken. Neem contact op met de ondersteuning als u hulp nodig hebt.",
|
||||
"unknownError": "Er is een onbekende fout opgetreden",
|
||||
"failedToStoreVault": "Vault opslaan mislukt",
|
||||
"vaultNotAvailable": "Vault niet beschikbaar",
|
||||
"failedToGetVault": "Vault ophalen mislukt",
|
||||
"vaultIsLocked": "Vault is vergrendeld",
|
||||
"failedToGetCredentials": "Inloggegevens ophalen mislukt",
|
||||
"failedToCreateIdentity": "Identiteit aanmaken mislukt",
|
||||
"failedToGetDefaultEmailDomain": "Standaard e-maildomein ophalen mislukt",
|
||||
"failedToGetDefaultIdentitySettings": "Standaard identiteitsinstellingen ophalen mislukt",
|
||||
"failedToGetPasswordSettings": "Wachtwoordinstellingen ophalen mislukt",
|
||||
"failedToUploadVault": "Vault uploaden mislukt",
|
||||
"noDerivedKeyAvailable": "Geen afgeleide sleutel beschikbaar voor versleuteling",
|
||||
"failedToUploadVaultToServer": "Nieuwe vault uploaden naar server mislukt",
|
||||
"noVaultOrDerivedKeyFound": "Geen vault of afgeleide sleutel gevonden"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "Er is een onbekende fout opgetreden. Probeer het opnieuw.",
|
||||
"ACCOUNT_LOCKED": "Account tijdelijk vergrendeld vanwege te veel mislukte pogingen. Probeer het later opnieuw.",
|
||||
"ACCOUNT_BLOCKED": "Uw account is uitgeschakeld. Als u denkt dat dit een vergissing is, neem dan contact op met de ondersteuning.",
|
||||
"USER_NOT_FOUND": "Gebruikersnaam of wachtwoord is onjuist. Probeer het opnieuw.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Ongeldige authenticatiecode. Probeer het opnieuw.",
|
||||
"INVALID_RECOVERY_CODE": "Ongeldige herstelcode. Probeer het opnieuw.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Vernieuwingstoken is vereist.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "Gebruiker niet gevonden in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "Gebruiker niet gevonden in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Ongeldig vernieuwingstoken.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Vernieuwingstoken succesvol ingetrokken.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "Registratie van nieuwe accounts is momenteel uitgeschakeld op deze server. Neem contact op met de beheerder.",
|
||||
"USERNAME_REQUIRED": "Gebruikersnaam is vereist.",
|
||||
"USERNAME_ALREADY_IN_USE": "Gebruikersnaam is al in gebruik.",
|
||||
"USERNAME_AVAILABLE": "Gebruikersnaam is beschikbaar.",
|
||||
"USERNAME_MISMATCH": "Gebruikersnaam komt niet overeen met de huidige gebruiker.",
|
||||
"PASSWORD_MISMATCH": "Het opgegeven wachtwoord komt niet overeen met uw huidige wachtwoord.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account succesvol verwijderd.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Gebruikersnaam mag niet leeg zijn of alleen uit spaties bestaan.",
|
||||
"USERNAME_TOO_SHORT": "Gebruikersnaam te kort: moet minimaal 3 tekens lang zijn.",
|
||||
"USERNAME_TOO_LONG": "Gebruikersnaam te lang: mag niet langer zijn dan 40 tekens.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Gebruikersnaam 'admin' is niet toegestaan.",
|
||||
"USERNAME_INVALID_EMAIL": "Ongeldig e-mailadres.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Gebruikersnaam is ongeldig, mag alleen letters of cijfers bevatten.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Uw kluis is niet up-to-date. Synchroniseer uw kluis en probeer het opnieuw.",
|
||||
"INTERNAL_SERVER_ERROR": "Interne serverfout.",
|
||||
"VAULT_ERROR": "De lokale kluis is niet up-to-date. Synchroniseer uw kluis door de pagina te vernieuwen en probeer het opnieuw."
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"new": "Nieuw",
|
||||
"cancel": "Annuleren",
|
||||
"search": "Zoeken",
|
||||
"vaultLocked": "AliasVault is vergrendeld.",
|
||||
"creatingNewAlias": "Nieuwe alias aanmaken...",
|
||||
"noMatchesFound": "Geen resultaten gevonden",
|
||||
"searchVault": "Kluis doorzoeken...",
|
||||
"serviceName": "Servicenaam",
|
||||
"email": "E-mail",
|
||||
"username": "Gebruikersnaam",
|
||||
"generatedPassword": "Gegenereerd wachtwoord",
|
||||
"enterServiceName": "Voer servicenaam in",
|
||||
"enterEmailAddress": "Voer e-mailadres in",
|
||||
"enterUsername": "Voer gebruikersnaam in",
|
||||
"hideFor1Hour": "Verberg voor 1 uur (huidige site)",
|
||||
"hidePermanently": "Permanent verbergen (huidige site)",
|
||||
"createRandomAlias": "Willekeurige alias aanmaken",
|
||||
"createUsernamePassword": "Gebruikersnaam/wachtwoord aanmaken",
|
||||
"randomAlias": "Willekeurige alias",
|
||||
"usernamePassword": "Gebruikersnaam/wachtwoord",
|
||||
"createAndSaveAlias": "Alias aanmaken en opslaan",
|
||||
"createAndSaveCredential": "Inloggegevens aanmaken en opslaan",
|
||||
"randomIdentityDescription": "Genereer een willekeurige identiteit met een willekeurig e-mailadres toegankelijk in AliasVault.",
|
||||
"manualCredentialDescription": "Specificeer je eigen e-mailadres en gebruikersnaam.",
|
||||
"failedToCreateIdentity": "Identiteit aanmaken mislukt. Probeer opnieuw.",
|
||||
"enterEmailAndOrUsername": "Voer e-mail en/of gebruikersnaam in",
|
||||
"autofillWithAliasVault": "Autofill met AliasVault",
|
||||
"generateRandomPassword": "Willekeurig wachtwoord genereren (kopiëren naar klembord)",
|
||||
"passwordCopiedToClipboard": "Wachtwoord gekopieerd naar klembord"
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Inloggegevens toevoegen",
|
||||
"editCredential": "Credential bewerken",
|
||||
"deleteCredential": "Credential verwijderen",
|
||||
"credentialDetails": "Credential details",
|
||||
"serviceName": "Naam dienst",
|
||||
"serviceNamePlaceholder": "bijv. Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://voorbeeld.nl",
|
||||
"username": "Gebruikersnaam",
|
||||
"usernamePlaceholder": "Voer gebruikersnaam in",
|
||||
"password": "Wachtwoord",
|
||||
"passwordPlaceholder": "Voer wachtwoord in",
|
||||
"generatePassword": "Wachtwoord genereren",
|
||||
"copyPassword": "Wachtwoord kopiëren",
|
||||
"showPassword": "Wachtwoord tonen",
|
||||
"hidePassword": "Wachtwoord verbergen",
|
||||
"notes": "Notities",
|
||||
"notesPlaceholder": "Aanvullende notities...",
|
||||
"totp": "Twee-factor-authenticatie",
|
||||
"totpCode": "TOTP-code",
|
||||
"copyTotp": "Kopiëren",
|
||||
"totpSecret": "TOTP-sleutel",
|
||||
"totpSecretPlaceholder": "Voer TOTP-secret key in",
|
||||
"noCredentials": "Geen credentials gevonden",
|
||||
"noCredentialsDescription": "Voeg je eerste credentials toe om te beginnen",
|
||||
"searchCredentials": "Zoek credentials...",
|
||||
"searchPlaceholder": "Credentials zoeken...",
|
||||
"welcomeTitle": "Welkom bij AliasVault!",
|
||||
"welcomeDescription": "Om de AliasVault browser extensie te gebruiken: navigeer naar een website en gebruik de AliasVault autofill popup om nieuwe credentials aan te maken.",
|
||||
"manualCreationHint": "Als je handmatig identiteiten wilt aanmaken, open dan de volledige AliasVault app via het uitklapicoon in de rechterbovenhoek.",
|
||||
"lastUsed": "Laatst gebruikt",
|
||||
"createdAt": "Aangemaakt",
|
||||
"updatedAt": "Laatst bijgewerkt",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Formulier invullen",
|
||||
"copyUsername": "Gebruikersnaam kopiëren",
|
||||
"openWebsite": "Website openen",
|
||||
"favorite": "Favoriet",
|
||||
"unfavorite": "Uit favorieten verwijderen",
|
||||
"deleteConfirm": "Weet u zeker dat u deze credential wilt verwijderen?",
|
||||
"deleteSuccess": "Credential succesvol verwijderd",
|
||||
"saveSuccess": "Credential succesvol opgeslagen",
|
||||
"copySuccess": "Gekopieerd naar klembord",
|
||||
"tags": "Labels",
|
||||
"addTag": "Label toevoegen",
|
||||
"removeTag": "Label verwijderen",
|
||||
"folder": "Map",
|
||||
"selectFolder": "Map selecteren",
|
||||
"createFolder": "Map aanmaken",
|
||||
"saveCredential": "Credential opslaan",
|
||||
"deleteCredentialTitle": "Credential verwijderen",
|
||||
"deleteCredentialConfirm": "Weet je zeker dat je deze credential wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.",
|
||||
"randomAlias": "Willekeurige alias",
|
||||
"manual": "Handmatig",
|
||||
"service": "Naam van dienst",
|
||||
"serviceUrl": "URL",
|
||||
"loginCredentials": "Inloggegevens",
|
||||
"generateRandomUsername": "Gebruikersnaam genereren",
|
||||
"generateRandomPassword": "Wachtwoord genereren",
|
||||
"generateRandomAlias": "Alias genereren",
|
||||
"alias": "Alias",
|
||||
"firstName": "Voornaam",
|
||||
"lastName": "Achternaam",
|
||||
"nickName": "Bijnaam",
|
||||
"gender": "Geslacht",
|
||||
"birthDate": "Geboortedatum",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Servicenaam is verplicht",
|
||||
"invalidUrl": "Voer een geldige URL in",
|
||||
"saveError": "Credential opslaan mislukt",
|
||||
"loadError": "Credential laden mislukt",
|
||||
"deleteError": "Credential verwijderen mislukt",
|
||||
"copyError": "Kopiëren naar klembord mislukt"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"title": "E-mail details",
|
||||
"deleteEmailTitle": "E-mail Verwijderen",
|
||||
"deleteEmailConfirm": "Weet u zeker dat u deze e-mail definitief wilt verwijderen?",
|
||||
"from": "Van",
|
||||
"to": "Naar",
|
||||
"date": "Datum",
|
||||
"emailContent": "E-mailinhoud",
|
||||
"attachments": "Bijlagen",
|
||||
"emailNotFound": "E-mail niet gevonden",
|
||||
"noEmails": "Geen e-mails gevonden",
|
||||
"errors": {
|
||||
"emailLoadError": "Er is een fout opgetreden bij het laden van e-mails. Probeer het later opnieuw.",
|
||||
"emailUnexpectedError": "Er is een onverwachte fout opgetreden bij het laden van e-mails. Probeer het later opnieuw."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "Het huidige gekozen e-mailadres is al in gebruik. Wijzig het e-mailadres door deze credential te bewerken.",
|
||||
"CLAIM_DOES_NOT_EXIST": "Er is een fout opgetreden bij het laden van e-mails. Probeer de credential te bewerken en op te slaan om de database te synchroniseren, en probeer het opnieuw."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"title": "Instellingen",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Taal",
|
||||
"autofillEnabled": "Autofill",
|
||||
"version": "Versie",
|
||||
"openInNewWindow": "Openen in nieuw venster",
|
||||
"openWebApp": "Web-app openen",
|
||||
"loggedIn": "Ingelogd",
|
||||
"logout": "Uitloggen",
|
||||
"globalSettings": "Globale Instellingen",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Actief voor alle sites (tenzij hieronder uitgeschakeld)",
|
||||
"disabledOnAllSites": "Uitgeschakeld op alle sites",
|
||||
"enabled": "Ingeschakeld",
|
||||
"disabled": "Uitgeschakeld",
|
||||
"rightClickContextMenu": "Rechts-klik contextmenu",
|
||||
"siteSpecificSettings": "Site-specifieke Instellingen",
|
||||
"autofillPopupOn": "Autofill popup op: ",
|
||||
"enabledForThisSite": "Ingeschakeld voor deze site",
|
||||
"disabledForThisSite": "Uitgeschakeld voor deze site",
|
||||
"temporarilyDisabledUntil": "Tijdelijk uitgeschakeld tot ",
|
||||
"resetAllSiteSettings": "Alle site-specifieke instellingen resetten",
|
||||
"appearance": "Uiterlijk",
|
||||
"theme": "Thema",
|
||||
"useDefault": "Standaard gebruiken",
|
||||
"light": "Licht",
|
||||
"dark": "Donker",
|
||||
"keyboardShortcuts": "Snelkoppelingen",
|
||||
"configureKeyboardShortcuts": "Snelkoppelingen configureren",
|
||||
"configure": "Configureren",
|
||||
"versionPrefix": "Versie ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is vereist",
|
||||
"apiUrlInvalid": "Voer een geldige API URL in",
|
||||
"clientUrlRequired": "Client URL is vereist",
|
||||
"clientUrlInvalid": "Voer een geldige client URL in"
|
||||
}
|
||||
}
|
||||
316
apps/browser-extension/src/locales/uk.json
Normal file
316
apps/browser-extension/src/locales/uk.json
Normal file
@@ -0,0 +1,316 @@
|
||||
{
|
||||
"auth": {
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"unlockSuccessTitle": "Your vault is successfully unlocked",
|
||||
"unlockSuccessDescription": "You can now use autofill in login forms in your browser.",
|
||||
"closePopup": "Close this popup",
|
||||
"browseVault": "Browse vault contents",
|
||||
"connectingTo": "Connecting to",
|
||||
"switchAccounts": "Switch accounts?",
|
||||
"loggedIn": "Logged in",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again.",
|
||||
"loginDataMissing": "Login session expired. Please try again."
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"credentials": "Credentials",
|
||||
"emails": "Emails",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"common": {
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation...",
|
||||
"errors": {
|
||||
"VaultMergeRequired": "Your vault needs to be updated. Please login on the AliasVault website and follow the steps.",
|
||||
"VaultOutdated": "Your vault is outdated. Please login on the AliasVault website and follow the steps.",
|
||||
"NoVaultFound": "Your account does not have a vault yet. Please complete the tutorial in the AliasVault web client before using the browser extension.",
|
||||
"serverNotAvailable": "The AliasVault server is not available. Please try again later or contact support if the problem persists.",
|
||||
"clientVersionNotSupported": "This version of the AliasVault browser extension is not supported by the server anymore. Please update your browser extension to the latest version.",
|
||||
"serverVersionNotSupported": "The AliasVault server needs to be updated to a newer version in order to use this browser extension. Please contact support if you need help.",
|
||||
"unknownError": "An unknown error occurred",
|
||||
"failedToStoreVault": "Failed to store vault",
|
||||
"vaultNotAvailable": "Vault not available",
|
||||
"failedToGetVault": "Failed to get vault",
|
||||
"vaultIsLocked": "Vault is locked",
|
||||
"failedToGetCredentials": "Failed to get credentials",
|
||||
"failedToCreateIdentity": "Failed to create identity",
|
||||
"failedToGetDefaultEmailDomain": "Failed to get default email domain",
|
||||
"failedToGetDefaultIdentitySettings": "Failed to get default identity settings",
|
||||
"failedToGetPasswordSettings": "Failed to get password settings",
|
||||
"failedToUploadVault": "Failed to upload vault",
|
||||
"noDerivedKeyAvailable": "No derived key available for encryption",
|
||||
"failedToUploadVaultToServer": "Failed to upload new vault to server",
|
||||
"noVaultOrDerivedKeyFound": "No vault or derived key found"
|
||||
},
|
||||
"apiErrors": {
|
||||
"UNKNOWN_ERROR": "An unknown error occurred. Please try again.",
|
||||
"ACCOUNT_LOCKED": "Account temporarily locked due to too many failed attempts. Please try again later.",
|
||||
"ACCOUNT_BLOCKED": "Your account has been disabled. If you believe this is a mistake, please contact support.",
|
||||
"USER_NOT_FOUND": "Invalid username or password. Please try again.",
|
||||
"INVALID_AUTHENTICATOR_CODE": "Invalid authenticator code. Please try again.",
|
||||
"INVALID_RECOVERY_CODE": "Invalid recovery code. Please try again.",
|
||||
"REFRESH_TOKEN_REQUIRED": "Refresh token is required.",
|
||||
"USER_NOT_FOUND_IN_TOKEN": "User not found in token.",
|
||||
"USER_NOT_FOUND_IN_DATABASE": "User not found in database.",
|
||||
"INVALID_REFRESH_TOKEN": "Invalid refresh token.",
|
||||
"REFRESH_TOKEN_REVOKED_SUCCESSFULLY": "Refresh token revoked successfully.",
|
||||
"PUBLIC_REGISTRATION_DISABLED": "New account registration is currently disabled on this server. Please contact the administrator.",
|
||||
"USERNAME_REQUIRED": "Username is required.",
|
||||
"USERNAME_ALREADY_IN_USE": "Username is already in use.",
|
||||
"USERNAME_AVAILABLE": "Username is available.",
|
||||
"USERNAME_MISMATCH": "Username does not match the current user.",
|
||||
"PASSWORD_MISMATCH": "The provided password does not match your current password.",
|
||||
"ACCOUNT_SUCCESSFULLY_DELETED": "Account successfully deleted.",
|
||||
"USERNAME_EMPTY_OR_WHITESPACE": "Username cannot be empty or whitespace.",
|
||||
"USERNAME_TOO_SHORT": "Username too short: must be at least 3 characters long.",
|
||||
"USERNAME_TOO_LONG": "Username too long: cannot be longer than 40 characters.",
|
||||
"USERNAME_ADMIN_NOT_ALLOWED": "Username 'admin' is not allowed.",
|
||||
"USERNAME_INVALID_EMAIL": "Invalid email address.",
|
||||
"USERNAME_INVALID_CHARACTERS": "Username is invalid, can only contain letters or digits.",
|
||||
"VAULT_NOT_UP_TO_DATE": "Your vault is not up-to-date. Please synchronize your vault and try again.",
|
||||
"INTERNAL_SERVER_ERROR": "Internal server error.",
|
||||
"VAULT_ERROR": "The local vault is not up-to-date. Please synchronize your vault by refreshing the page and try again."
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"new": "New",
|
||||
"cancel": "Cancel",
|
||||
"search": "Search",
|
||||
"vaultLocked": "AliasVault is locked.",
|
||||
"creatingNewAlias": "Creating new alias...",
|
||||
"noMatchesFound": "No matches found",
|
||||
"searchVault": "Search vault...",
|
||||
"serviceName": "Service name",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"generatedPassword": "Generated Password",
|
||||
"enterServiceName": "Enter service name",
|
||||
"enterEmailAddress": "Enter email address",
|
||||
"enterUsername": "Enter username",
|
||||
"hideFor1Hour": "Hide for 1 hour (current site)",
|
||||
"hidePermanently": "Hide permanently (current site)",
|
||||
"createRandomAlias": "Create random alias",
|
||||
"createUsernamePassword": "Create username/password",
|
||||
"randomAlias": "Random alias",
|
||||
"usernamePassword": "Username/password",
|
||||
"createAndSaveAlias": "Create and save alias",
|
||||
"createAndSaveCredential": "Create and save credential",
|
||||
"randomIdentityDescription": "Generate a random identity with a random email address accessible in AliasVault.",
|
||||
"randomIdentityDescriptionDropdown": "Random identity with random email",
|
||||
"manualCredentialDescription": "Specify your own email address and username.",
|
||||
"manualCredentialDescriptionDropdown": "Manual username and password",
|
||||
"failedToCreateIdentity": "Failed to create identity. Please try again.",
|
||||
"enterEmailAndOrUsername": "Enter email and/or username",
|
||||
"autofillWithAliasVault": "Autofill with AliasVault",
|
||||
"generateRandomPassword": "Generate random password (copy to clipboard)",
|
||||
"generateNewPassword": "Generate new password",
|
||||
"togglePasswordVisibility": "Toggle password visibility",
|
||||
"passwordCopiedToClipboard": "Password copied to clipboard",
|
||||
"enterEmailAndOrUsernameError": "Enter email and/or username",
|
||||
"openAliasVaultToUpgrade": "Open AliasVault to upgrade",
|
||||
"vaultUpgradeRequired": "Vault upgrade required.",
|
||||
"dismissPopup": "Dismiss popup"
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
},
|
||||
"emails": {
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
},
|
||||
"apiErrors": {
|
||||
"CLAIM_DOES_NOT_MATCH_USER": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"CLAIM_DOES_NOT_EXIST": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version ",
|
||||
"validation": {
|
||||
"apiUrlRequired": "API URL is required",
|
||||
"apiUrlInvalid": "Please enter a valid API URL",
|
||||
"clientUrlRequired": "Client URL is required",
|
||||
"clientUrlInvalid": "Please enter a valid client URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"loginTitle": "Log in to AliasVault",
|
||||
"username": "Username or email",
|
||||
"usernamePlaceholder": "name / name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"rememberMe": "Remember me",
|
||||
"loginButton": "Login",
|
||||
"noAccount": "No account yet?",
|
||||
"createVault": "Create new vault",
|
||||
"twoFactorTitle": "Please enter the authentication code from your authenticator app.",
|
||||
"authCode": "Authentication Code",
|
||||
"authCodePlaceholder": "Enter 6-digit code",
|
||||
"verify": "Verify",
|
||||
"cancel": "Cancel",
|
||||
"twoFactorNote": "Note: if you don't have access to your authenticator device, you can reset your 2FA with a recovery code by logging in via the website.",
|
||||
"masterPassword": "Master Password",
|
||||
"unlockVault": "Unlock Vault",
|
||||
"unlockTitle": "Unlock Your Vault",
|
||||
"unlockDescription": "Enter your master password to unlock your vault.",
|
||||
"logout": "Logout",
|
||||
"logoutConfirm": "Are you sure you want to logout?",
|
||||
"sessionExpired": "Your session has expired. Please log in again.",
|
||||
"unlockSuccess": "Vault unlocked successfully!",
|
||||
"connectingTo": "Connecting to",
|
||||
"errors": {
|
||||
"invalidCode": "Please enter a valid 6-digit authentication code.",
|
||||
"serverError": "Could not reach AliasVault server. Please try again later or contact support if the problem persists.",
|
||||
"noToken": "Login failed -- no token returned",
|
||||
"migrationError": "An error occurred while checking for pending migrations.",
|
||||
"wrongPassword": "Incorrect password. Please try again.",
|
||||
"accountLocked": "Account temporarily locked due to too many failed attempts.",
|
||||
"networkError": "Network error. Please check your connection and try again."
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"appName": "AliasVault",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete",
|
||||
"close": "Close",
|
||||
"copied": "Copied!",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"language": "Language",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"showPassword": "Show password",
|
||||
"hidePassword": "Hide password",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"loadingEmails": "Loading emails...",
|
||||
"loadingTotpCodes": "Loading TOTP codes...",
|
||||
"settings": "Settings",
|
||||
"recentEmails": "Recent emails",
|
||||
"loginCredentials": "Login credentials",
|
||||
"twoFactorAuthentication": "Two-factor authentication",
|
||||
"alias": "Alias",
|
||||
"notes": "Notes",
|
||||
"fullName": "Full Name",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"birthDate": "Birth Date",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"syncingVault": "Syncing vault",
|
||||
"savingChangesToVault": "Saving changes to vault",
|
||||
"uploadingVaultToServer": "Uploading vault to server",
|
||||
"checkingVaultUpdates": "Checking for vault updates",
|
||||
"syncingUpdatedVault": "Syncing updated vault",
|
||||
"executingOperation": "Executing operation..."
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"title": "Credentials",
|
||||
"addCredential": "Add Credential",
|
||||
"editCredential": "Edit Credential",
|
||||
"deleteCredential": "Delete Credential",
|
||||
"credentialDetails": "Credential Details",
|
||||
"serviceName": "Service Name",
|
||||
"serviceNamePlaceholder": "e.g., Gmail, Facebook, Bank",
|
||||
"website": "Website",
|
||||
"websitePlaceholder": "https://example.com",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter password",
|
||||
"generatePassword": "Generate Password",
|
||||
"copyPassword": "Copy Password",
|
||||
"showPassword": "Show Password",
|
||||
"hidePassword": "Hide Password",
|
||||
"notes": "Notes",
|
||||
"notesPlaceholder": "Additional notes...",
|
||||
"totp": "Two-Factor Authentication",
|
||||
"totpCode": "TOTP Code",
|
||||
"copyTotp": "Copy TOTP",
|
||||
"totpSecret": "TOTP Secret",
|
||||
"totpSecretPlaceholder": "Enter TOTP secret key",
|
||||
"noCredentials": "No credentials found",
|
||||
"noCredentialsDescription": "Add your first credential to get started",
|
||||
"searchCredentials": "Search credentials...",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"welcomeTitle": "Welcome to AliasVault!",
|
||||
"welcomeDescription": "To use the AliasVault browser extension: navigate to a website and use the AliasVault autofill popup to create a new credential.",
|
||||
"manualCreationHint": "If you want to create manual identities, open the full AliasVault app via the popout icon in the top right corner.",
|
||||
"lastUsed": "Last used",
|
||||
"createdAt": "Created",
|
||||
"updatedAt": "Last updated",
|
||||
"autofill": "Autofill",
|
||||
"fillForm": "Fill Form",
|
||||
"copyUsername": "Copy Username",
|
||||
"openWebsite": "Open Website",
|
||||
"favorite": "Favorite",
|
||||
"unfavorite": "Remove from Favorites",
|
||||
"deleteConfirm": "Are you sure you want to delete this credential?",
|
||||
"deleteSuccess": "Credential deleted successfully",
|
||||
"saveSuccess": "Credential saved successfully",
|
||||
"copySuccess": "Copied to clipboard",
|
||||
"tags": "Tags",
|
||||
"addTag": "Add Tag",
|
||||
"removeTag": "Remove Tag",
|
||||
"folder": "Folder",
|
||||
"selectFolder": "Select Folder",
|
||||
"createFolder": "Create Folder",
|
||||
"saveCredential": "Save credential",
|
||||
"deleteCredentialTitle": "Delete Credential",
|
||||
"deleteCredentialConfirm": "Are you sure you want to delete this credential? This action cannot be undone.",
|
||||
"randomAlias": "Random Alias",
|
||||
"manual": "Manual",
|
||||
"service": "Service",
|
||||
"serviceUrl": "Service URL",
|
||||
"loginCredentials": "Login Credentials",
|
||||
"generateRandomUsername": "Generate random username",
|
||||
"generateRandomPassword": "Generate random password",
|
||||
"generateRandomAlias": "Generate Random Alias",
|
||||
"alias": "Alias",
|
||||
"firstName": "First Name",
|
||||
"lastName": "Last Name",
|
||||
"nickName": "Nick Name",
|
||||
"gender": "Gender",
|
||||
"birthDate": "Birth Date",
|
||||
"birthDatePlaceholder": "YYYY-MM-DD",
|
||||
"metadata": "Metadata",
|
||||
"errors": {
|
||||
"serviceNameRequired": "Service name is required",
|
||||
"invalidUrl": "Please enter a valid URL",
|
||||
"saveError": "Failed to save credential",
|
||||
"loadError": "Failed to load credentials",
|
||||
"deleteError": "Failed to delete credential",
|
||||
"copyError": "Failed to copy to clipboard"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "Email Details",
|
||||
"deleteEmailTitle": "Delete Email",
|
||||
"deleteEmailConfirm": "Are you sure you want to permanently delete this email?",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"date": "Date",
|
||||
"emailContent": "Email content",
|
||||
"attachments": "Attachments",
|
||||
"emailNotFound": "Email not found",
|
||||
"noEmails": "No emails found",
|
||||
"errors": {
|
||||
"emailLoadError": "An error occurred while loading emails. Please try again later.",
|
||||
"emailInUse": "The current chosen email address is already in use. Please change the email address by editing this credential.",
|
||||
"emailSyncError": "An error occurred while trying to load the emails. Please try to edit and save the credential entry to synchronize the database, then try again.",
|
||||
"emailUnexpectedError": "An unexpected error occurred while loading emails. Please try again later."
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"serverUrl": "Server URL",
|
||||
"language": "Language",
|
||||
"autofillEnabled": "Enable Autofill",
|
||||
"version": "Version",
|
||||
"openInNewWindow": "Open in new window",
|
||||
"openWebApp": "Open web app",
|
||||
"loggedIn": "Logged in",
|
||||
"logout": "Logout",
|
||||
"globalSettings": "Global Settings",
|
||||
"autofillPopup": "Autofill popup",
|
||||
"activeOnAllSites": "Active on all sites (unless disabled below)",
|
||||
"disabledOnAllSites": "Disabled on all sites",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"rightClickContextMenu": "Right-click context menu",
|
||||
"siteSpecificSettings": "Site-Specific Settings",
|
||||
"autofillPopupOn": "Autofill popup on: ",
|
||||
"enabledForThisSite": "Enabled for this site",
|
||||
"disabledForThisSite": "Disabled for this site",
|
||||
"temporarilyDisabledUntil": "Temporarily disabled until ",
|
||||
"resetAllSiteSettings": "Reset all site-specific settings",
|
||||
"appearance": "Appearance",
|
||||
"theme": "Theme",
|
||||
"useDefault": "Use default",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"keyboardShortcuts": "Keyboard Shortcuts",
|
||||
"configureKeyboardShortcuts": "Configure keyboard shortcuts",
|
||||
"configure": "Configure",
|
||||
"versionPrefix": "Version "
|
||||
}
|
||||
@@ -1,34 +1,18 @@
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
// Import all translations
|
||||
import authEn from '../locales/en/auth.json';
|
||||
import commonEn from '../locales/en/common.json';
|
||||
import credentialsEn from '../locales/en/credentials.json';
|
||||
import emailsEn from '../locales/en/emails.json';
|
||||
import settingsEn from '../locales/en/settings.json';
|
||||
import authNl from '../locales/nl/auth.json';
|
||||
import commonNl from '../locales/nl/common.json';
|
||||
import credentialsNl from '../locales/nl/credentials.json';
|
||||
import emailsNl from '../locales/nl/emails.json';
|
||||
import settingsNl from '../locales/nl/settings.json';
|
||||
// Import consolidated translations
|
||||
import enTranslations from '../locales/en.json';
|
||||
import nlTranslations from '../locales/nl.json';
|
||||
|
||||
import { storage } from '#imports';
|
||||
|
||||
const resources = {
|
||||
en: {
|
||||
common: commonEn,
|
||||
auth: authEn,
|
||||
credentials: credentialsEn,
|
||||
settings: settingsEn,
|
||||
emails: emailsEn
|
||||
translation: enTranslations
|
||||
},
|
||||
nl: {
|
||||
common: commonNl,
|
||||
auth: authNl,
|
||||
credentials: credentialsNl,
|
||||
settings: settingsNl,
|
||||
emails: emailsNl
|
||||
translation: nlTranslations
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { storage } from '#imports';
|
||||
* Type for content translations
|
||||
*/
|
||||
export type ContentTranslations = {
|
||||
[key: string]: string;
|
||||
[key: string]: string | ContentTranslations;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -38,10 +38,10 @@ export async function getCurrentLanguage(): Promise<string> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load translations for a specific namespace and language
|
||||
* Load translations for a specific language
|
||||
*/
|
||||
async function loadTranslations(namespace: string, language: string): Promise<ContentTranslations> {
|
||||
const cacheKey = `${namespace}:${language}`;
|
||||
async function loadTranslations(language: string): Promise<ContentTranslations> {
|
||||
const cacheKey = `all:${language}`;
|
||||
|
||||
// Check cache first
|
||||
if (translationCache.has(cacheKey)) {
|
||||
@@ -49,8 +49,8 @@ async function loadTranslations(namespace: string, language: string): Promise<Co
|
||||
}
|
||||
|
||||
try {
|
||||
// Dynamically import the translation file
|
||||
const translations = await import(`../../locales/${language}/${namespace}.json`);
|
||||
// Dynamically import the consolidated translation file
|
||||
const translations = await import(`../../locales/${language}.json`);
|
||||
const translationData = translations.default || translations;
|
||||
|
||||
// Cache the translations
|
||||
@@ -58,12 +58,12 @@ async function loadTranslations(namespace: string, language: string): Promise<Co
|
||||
|
||||
return translationData;
|
||||
} catch (error) {
|
||||
console.warn(`Failed to load translations for ${namespace}:${language}`, error);
|
||||
console.warn(`Failed to load translations for ${language}`, error);
|
||||
|
||||
// Fallback to English if available
|
||||
if (language !== 'en') {
|
||||
try {
|
||||
const fallbackTranslations = await import(`../../locales/en/${namespace}.json`);
|
||||
const fallbackTranslations = await import(`../../locales/en.json`);
|
||||
const fallbackData = fallbackTranslations.default || fallbackTranslations;
|
||||
translationCache.set(cacheKey, fallbackData);
|
||||
return fallbackData;
|
||||
@@ -80,21 +80,19 @@ async function loadTranslations(namespace: string, language: string): Promise<Co
|
||||
/**
|
||||
* Translation function for non-React contexts
|
||||
*
|
||||
* @param key - Translation key (supports nested keys like 'errors.networkError')
|
||||
* @param namespace - Translation namespace (default: 'content')
|
||||
* @param key - Translation key (supports nested keys like 'auth.loginButton' or 'common.errors.networkError')
|
||||
* @param fallback - Fallback text if translation is not found
|
||||
* @returns Promise<string> - Translated text
|
||||
*/
|
||||
export async function t(
|
||||
key: string,
|
||||
namespace: string = 'content',
|
||||
fallback?: string
|
||||
): Promise<string> {
|
||||
try {
|
||||
const language = await getCurrentLanguage();
|
||||
const translations = await loadTranslations(namespace, language);
|
||||
const translations = await loadTranslations(language);
|
||||
|
||||
// Support nested keys like 'errors.networkError'
|
||||
// Support nested keys like 'auth.loginButton' or 'common.errors.networkError'
|
||||
const value = getNestedValue(translations, key);
|
||||
|
||||
if (value && typeof value === 'string') {
|
||||
@@ -103,7 +101,7 @@ export async function t(
|
||||
|
||||
// If translation not found and we're not using English, try English fallback
|
||||
if (language !== 'en') {
|
||||
const englishTranslations = await loadTranslations(namespace, 'en');
|
||||
const englishTranslations = await loadTranslations('en');
|
||||
const englishValue = getNestedValue(englishTranslations, key);
|
||||
|
||||
if (englishValue && typeof englishValue === 'string') {
|
||||
@@ -123,74 +121,9 @@ export async function t(
|
||||
* Get nested value from object using dot notation
|
||||
*/
|
||||
function getNestedValue(obj: Record<string, unknown>, path: string): unknown {
|
||||
return path.split('.').reduce((current, key) => {
|
||||
return current && current[key] !== undefined ? current[key] : undefined;
|
||||
return path.split('.').reduce((current: unknown, key: string) => {
|
||||
return current && typeof current === 'object' && current !== null && key in current
|
||||
? (current as Record<string, unknown>)[key]
|
||||
: undefined;
|
||||
}, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translation function specifically for content scripts
|
||||
* This is a convenience wrapper around the main t() function
|
||||
*/
|
||||
export async function tc(key: string, fallback?: string): Promise<string> {
|
||||
return t(key, 'content', fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translation function for errors namespace
|
||||
*/
|
||||
export async function te(key: string, fallback?: string): Promise<string> {
|
||||
return t(key, 'errors', fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translation function for common namespace
|
||||
*/
|
||||
export async function tcommon(key: string, fallback?: string): Promise<string> {
|
||||
return t(key, 'common', fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear translation cache (useful for language changes)
|
||||
*/
|
||||
export function clearTranslationCache(): void {
|
||||
translationCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-load common translations for use in synchronous contexts
|
||||
*/
|
||||
export async function preloadTranslationsForSync(
|
||||
namespaces: string[] = ['common', 'errors']
|
||||
): Promise<Record<string, ContentTranslations>> {
|
||||
const languages = ['en', 'nl'];
|
||||
const translations: Record<string, ContentTranslations> = {};
|
||||
|
||||
for (const lang of languages) {
|
||||
const langTranslations: ContentTranslations = {};
|
||||
|
||||
for (const namespace of namespaces) {
|
||||
try {
|
||||
const nsTranslations = await loadTranslations(namespace, lang);
|
||||
// Flatten the namespace structure for easier access
|
||||
Object.keys(nsTranslations).forEach(key => {
|
||||
if (namespace === 'common' && key === 'errors') {
|
||||
// Handle nested errors object
|
||||
const errors = nsTranslations[key] as Record<string, string>;
|
||||
Object.keys(errors).forEach(errorKey => {
|
||||
langTranslations[`errors.${errorKey}`] = errors[errorKey];
|
||||
});
|
||||
} else {
|
||||
langTranslations[key] = nsTranslations[key];
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`Failed to preload ${namespace} translations for ${lang}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
translations[lang] = langTranslations;
|
||||
}
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ files:
|
||||
type: resx
|
||||
translation_replace:
|
||||
.en: ''
|
||||
- source: /apps/browser-extension/src/locales/en/**/*.json
|
||||
translation: /apps/browser-extension/src/locales/%two_letters_code%/%file_name%.%file_extension%
|
||||
- source: /apps/browser-extension/src/locales/en.json
|
||||
translation: /apps/browser-extension/src/locales/%two_letters_code%.json
|
||||
type: json
|
||||
- source: /apps/mobile-app/i18n/locales/en.json
|
||||
translation: /apps/mobile-app/i18n/locales/%two_letters_code%.json
|
||||
|
||||
Reference in New Issue
Block a user