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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions Assets/js/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { getCountries } from './data/countries';
import { languages } from './data/languages';
import { createDialog, initDialog } from './dialog';
import './settings/device';
import { initLocalization } from './util/localization';
import { applyLocalization, initLocalization } from './util/localization';
import { validateMfaToken, validatePw } from './util/validation';

let currentUser;
Expand Down Expand Up @@ -231,12 +231,14 @@ LoginManager.isLoggedIn().then(async (e) => {
if (currentUser['2fa'] && currentUser['2faType'] === 'App') document.getElementById('cp_2fa').classList.remove('d-none');

if (currentUser['2fa']) {
document.getElementById('2fa_status').innerText = 'Enabled';
document.getElementById('2fa_status').innerText = i18next.t('profile_enabled');
document.getElementById('2fa_type').value = currentUser['2faType'] === 'App' ? 0 : currentUser['2faType'] === 'Mail' ? 1 : 2;
document.getElementById('2fa_type').disabled = true;
document.getElementById('2fa_enable').innerText = 'Disable';
document.getElementById('2fa_enable').innerText = i18next.t('profile_disable');
document.getElementById('2fa_enable').addEventListener('click', disable2fa);
} else {
document.getElementById('2fa_status').innerText = i18next.t('profile_disabled');
document.getElementById('2fa_enable').innerText = i18next.t('profile_enable');
document.getElementById('2fa_enable').addEventListener('click', enable2fa);
}

Expand Down Expand Up @@ -269,7 +271,7 @@ LoginManager.isLoggedIn().then(async (e) => {
name.innerText = client.name;
row.appendChild(name);
const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deleteTrustedSsoClient(client.id));
row.appendChild(deleteBtn);
document.getElementById('thirdPartyAppsContainer').appendChild(row);
Expand Down Expand Up @@ -313,24 +315,24 @@ async function buildPasskeys(keys) {
itemText.appendChild(keyElement);

const lastLogin = document.createElement('p');
lastLogin.innerText = `Last login: ${new Date(key.lastLogin).toLocaleString()}`;
lastLogin.innerText = `${i18next.t('profile_lastLogin')} ${new Date(key.lastLogin).toLocaleString()}`;
itemText.appendChild(lastLogin);

const createdAt = document.createElement('p');
createdAt.innerText = `Created at: ${new Date(key.createdAt).toLocaleString()}`;
createdAt.innerText = `${i18next.t('profile_createdAt')} ${new Date(key.createdAt).toLocaleString()}`;
itemText.appendChild(createdAt);

item.appendChild(itemText);

const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deletePasskey(key.id));
item.appendChild(deleteBtn);

container.appendChild(item);
});

if (keys.length === 0) container.innerHTML = '<p>No passkeys found!</p>';
if (keys.length === 0) container.innerHTML = `<p>${i18next.t('profile_noPasskeys')}</p>`;

document.getElementById('createPasskey').onclick = async () => await createPasskey();
}
Expand All @@ -342,7 +344,7 @@ async function deletePasskey(id) {

const container = document.getElementById('passkeysTable');

if (container.children.length === 0) container.innerHTML = '<p>No passkeys found!</p>';
if (container.children.length === 0) container.innerHTML = `<p>${i18next.t('profile_noPasskeys')}</p>`;
}

async function createPasskey() {
Expand Down Expand Up @@ -383,7 +385,7 @@ async function deleteTrustedSsoClient(clientId) {

const container = document.getElementById('thirdPartyAppsContainer');

if (container.children.length === 0) container.innerHTML = '<p>No third party apps connected!</p>';
if (container.children.length === 0) container.innerHTML = `<p>${i18next.t('profile_noThirdPartyApps')}</p>`;
}

async function createSsoCredentials() {
Expand Down Expand Up @@ -460,6 +462,8 @@ function createSSOClient(logoUrl, clientName, websiteUrl, clientId, clientSecret
content.querySelector('#sso_addRedirect').addEventListener('click', async () => await addSSORedirect(clientId));
content.querySelector('#sso_addAudience').addEventListener('click', async () => await addAudience(clientId));

applyLocalization(item);

const audiencesContainer = content.querySelector('#sso_audiences');

audiences.forEach((audience) => {
Expand All @@ -473,7 +477,7 @@ function createSSOClient(logoUrl, clientName, websiteUrl, clientId, clientSecret
audienceItem.appendChild(audienceInput);

const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deleteAudience(clientId, audience.id));
audienceItem.appendChild(deleteBtn);

Expand All @@ -493,7 +497,7 @@ function createSSOClient(logoUrl, clientName, websiteUrl, clientId, clientSecret
redirectItem.appendChild(url);

const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deleteSSORedirect(clientId, redirect.id));
redirectItem.appendChild(deleteBtn);

Expand Down Expand Up @@ -563,7 +567,7 @@ async function addAudience(clientId) {
url.disabled = true;
redirect.appendChild(url);
const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deleteAudienceReq(clientId, res.data.id));
redirect.appendChild(deleteBtn);

Expand Down Expand Up @@ -599,7 +603,7 @@ async function addSSORedirect(clientId) {
url.disabled = true;
redirect.appendChild(url);
const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => await deleteSSORedirect(clientId, res.data.id));
redirect.appendChild(deleteBtn);

Expand Down Expand Up @@ -632,11 +636,11 @@ async function doubleClickButton(e, func) {
}

e.target.dataset.clicked = 'true';
e.target.innerText = 'Confirm';
e.target.innerText = i18next.t('profile_confirm');

setTimeout(() => {
e.target.dataset.clicked = 'false';
e.target.innerText = 'Delete Account';
e.target.innerText = i18next.t('profile_deleteAccount');
}, 3000);
}

Expand All @@ -647,8 +651,8 @@ function createApiKeyRow(label, client_id, scope) {
const td = document.createElement('td');
const deleteBtn = document.createElement('button');
const regenBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
regenBtn.innerText = 'Regenerate';
deleteBtn.innerText = i18next.t('profile_delete');
regenBtn.innerText = i18next.t('profile_regenerate');

deleteBtn.addEventListener('click', () => deleteApiKey(client_id));
regenBtn.addEventListener('click', () => regenerateApiKey(client_id));
Expand Down
11 changes: 6 additions & 5 deletions Assets/js/settings/device.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import i18next from 'i18next';
import { deleteDevice } from '../data/auth/deleteDevice';
import { getDevices } from '../data/auth/getDevices';
import { logoutAllDevices } from '../data/auth/logoutAllDevices';
Expand Down Expand Up @@ -37,7 +38,7 @@ function createDevices(devices) {

if (devices.length === 0) {
const noDevices = document.createElement('p');
noDevices.innerText = 'No devices found.';
noDevices.innerText = i18next.t('profile_noDevices');
document.getElementById('devicesContainer').appendChild(noDevices);
return;
}
Expand All @@ -48,14 +49,14 @@ function createDevices(devices) {
const name = document.createElement('h1');
name.innerText = `${device.os} ${device.browser}`;

if (device.isCurrentDevice === true) name.innerText += ' (Current Device)';
if (device.isCurrentDevice === true) name.innerText += ` ${i18next.t('profile_currentDevice')}`;

row.appendChild(name);
const lastUsed = document.createElement('p');
lastUsed.innerText = `Last used: ${new Date(device.lastLogin).toLocaleString()}`;
lastUsed.innerText = `${i18next.t('profile_lastUsed')} ${new Date(device.lastLogin).toLocaleString()}`;
row.appendChild(lastUsed);
const logoutBtn = document.createElement('button');
logoutBtn.innerText = 'Logout';
logoutBtn.innerText = i18next.t('profile_logout');
logoutBtn.addEventListener('click', async () => {
await logoutDevice(device.id);

Expand All @@ -67,7 +68,7 @@ function createDevices(devices) {
row.appendChild(logoutBtn);

const deleteBtn = document.createElement('button');
deleteBtn.innerText = 'Delete';
deleteBtn.innerText = i18next.t('profile_delete');
deleteBtn.addEventListener('click', async () => {
await deleteDevice(device.id);

Expand Down
2 changes: 1 addition & 1 deletion Assets/js/util/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function initLocalization() {

export function applyLocalization(area = document) {
area.querySelectorAll('[i18n]').forEach((element) => {
element.innerText = i18next.t(element.getAttribute('i18n')) + element.innerText;
element.innerText = i18next.t(element.getAttribute('i18n'));
});

area.querySelectorAll('[i18n-placeholder]').forEach((element) => {
Expand Down
84 changes: 83 additions & 1 deletion Assets/locales/de.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,85 @@
{
"lang": "Deutsch"
"lang": "Deutsch",
"brand": "Netdb",
"login": "Anmelden",
"productsTitle": "Produkte",
"products": {},
"status": "Status",
"services": "Dienste",
"contact": "Kontakt",
"profile_back": "Zurück",
"profile_accountManagement": "Kontoverwaltung",
"profile_general": "Allgemein",
"profile_personalInformation": "Persönliche Informationen",
"profile_password": "Passwort",
"profile_connectedAccounts": "Verknüpfte Konten",
"profile_security": "Sicherheit",
"profile_twoFactorAuth": "Zwei-Faktor-Authentifizierung",
"profile_passkeys": "Passkeys",
"profile_myDevices": "Meine Geräte",
"profile_thirdPartyApps": "Drittanbieter-Apps",
"profile_developer": "Entwickler",
"profile_apiKeys": "API-Schlüssel",
"profile_ssoCredentials": "SSO-Anmeldedaten", "profile_logout": "Abmelden",
"profile_deleteAccount": "Konto löschen",
"profile_dangerZone": "Gefahrenzone",
"profile_disconnect": "Trennen",
"profile_save": "Speichern",
"profile_delete": "Löschen",
"profile_create": "Erstellen",
"profile_confirm": "Bestätigen",
"profile_createNew": "Neu erstellen",
"profile_add": "Hinzufügen",
"profile_regenerate": "Neu generieren",
"profile_status": "Status:",
"profile_type": "Typ:",
"profile_disabled": "Deaktiviert",
"profile_enabled": "Aktiviert",
"profile_authenticator": "Authenticator",
"profile_emailType": "E-Mail",
"profile_selectType": "Bitte Typ auswählen",
"profile_enable": "Aktivieren",
"profile_disable": "Deaktivieren",
"profile_createPasskey": "Passkey erstellen",
"profile_logoutAllDevices": "Alle Geräte abmelden",
"profile_noThirdPartyApps": "Keine Drittanbieter-Apps verbunden!",
"profile_label": "Bezeichnung",
"profile_key": "Schlüssel",
"profile_scope": "Bereich",
"profile_actions": "Aktionen",
"profile_singleSignOn": "Single Sign-On-Anmeldedaten",
"profile_noSsoClients": "Keine SSO-Clients gefunden!",
"profile_clientId": "Client-ID",
"profile_clientSecret": "Client-Geheimnis",
"profile_logoUrl": "Logo-URL",
"profile_websiteUrl": "Website-URL",
"profile_name": "Name",
"profile_audiences": "Zielgruppen",
"profile_redirects": "Weiterleitungen",
"profile_createSsoClient": "Neuen SSO-Client erstellen",
"profile_warning": "Warnung:",
"profile_dangerWarning": "Das Löschen Ihres Kontos ist unwiderruflich. Alle Ihre Daten werden gelöscht und können nicht wiederhergestellt werden.",
"profile_noPasskeys": "Keine Passkeys gefunden!",
"profile_lastLogin": "Letzter Login:",
"profile_createdAt": "Erstellt am:",
"profile_currentDevice": "(Aktuelles Gerät)",
"profile_noDevices": "Keine Geräte gefunden.",
"profile_lastUsed": "Zuletzt verwendet:",
"profile_placeholder_email": "E-Mail",
"profile_placeholder_username": "Benutzername",
"profile_placeholder_firstname": "Vorname",
"profile_placeholder_lastname": "Nachname",
"profile_placeholder_country": "Land",
"profile_placeholder_preferredLanguage": "Bevorzugte Sprache",
"profile_placeholder_oldPassword": "Altes Passwort",
"profile_placeholder_newPassword": "Neues Passwort",
"profile_placeholder_repeatPassword": "Passwort wiederholen",
"profile_placeholder_2faToken": "2FA-Token",
"profile_placeholder_label": "Bezeichnung",
"profile_placeholder_scope": "Bereich",
"profile_placeholder_password": "Passwort",
"profile_placeholder_mfaToken": "MFA-Token",
"profile_placeholder_name": "Name",
"profile_placeholder_url": "URL",
"profile_placeholder_logoUrl": "Logo-URL"
}
78 changes: 77 additions & 1 deletion Assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,81 @@
},
"status": "Status",
"services": "Services",
"contact": "Contact Us"
"contact": "Contact Us",
"profile_back": "Back",
"profile_accountManagement": "Account Management",
"profile_general": "General",
"profile_personalInformation": "Personal Information",
"profile_password": "Password",
"profile_connectedAccounts": "Connected Accounts",
"profile_security": "Security",
"profile_twoFactorAuth": "Two Factor Authentication",
"profile_passkeys": "Passkeys",
"profile_myDevices": "My Devices",
"profile_thirdPartyApps": "Third Party Apps",
"profile_developer": "Developer",
"profile_apiKeys": "API Keys",
"profile_ssoCredentials": "SSO Credentials",
"profile_logout": "Logout",
"profile_deleteAccount": "Delete Account",
"profile_dangerZone": "Danger Zone",
"profile_disconnect": "Disconnect",
"profile_save": "Save",
"profile_delete": "Delete",
"profile_create": "Create",
"profile_confirm": "Confirm",
"profile_createNew": "Create new",
"profile_add": "Add",
"profile_regenerate": "Regenerate",
"profile_status": "Status:",
"profile_type": "Type:",
"profile_disabled": "Disabled",
"profile_enabled": "Enabled",
"profile_authenticator": "Authenticator",
"profile_emailType": "Email",
"profile_selectType": "Please select a type",
"profile_enable": "Enable",
"profile_disable": "Disable",
"profile_createPasskey": "Create Passkey",
"profile_logoutAllDevices": "Logout all devices",
"profile_noThirdPartyApps": "No third party apps connected!",
"profile_label": "Label",
"profile_key": "Key",
"profile_scope": "Scope",
"profile_actions": "Actions",
"profile_singleSignOn": "Single Sign On Credentials",
"profile_noSsoClients": "No sso clients found!",
"profile_clientId": "Client Id",
"profile_clientSecret": "Client Secret",
"profile_logoUrl": "Logo Url",
"profile_websiteUrl": "Website Url",
"profile_name": "Name",
"profile_audiences": "Audiences",
"profile_redirects": "Redirects",
"profile_createSsoClient": "Create new SSO client",
"profile_warning": "Warning:",
"profile_dangerWarning": "Deleting your account is irreversible. All your data will be deleted and cannot be restored.",
"profile_noPasskeys": "No passkeys found!",
"profile_lastLogin": "Last login:",
"profile_createdAt": "Created at:",
"profile_currentDevice": "(Current Device)",
"profile_noDevices": "No devices found.",
"profile_lastUsed": "Last used:",
"profile_placeholder_email": "Email",
"profile_placeholder_username": "Username",
"profile_placeholder_firstname": "Firstname",
"profile_placeholder_lastname": "Lastname",
"profile_placeholder_country": "Country",
"profile_placeholder_preferredLanguage": "Preferred Language",
"profile_placeholder_oldPassword": "Old Password",
"profile_placeholder_newPassword": "New Password",
"profile_placeholder_repeatPassword": "Repeat Password",
"profile_placeholder_2faToken": "2fa Token",
"profile_placeholder_label": "Label",
"profile_placeholder_scope": "Scope",
"profile_placeholder_password": "Password",
"profile_placeholder_mfaToken": "MFA Token",
"profile_placeholder_name": "Name",
"profile_placeholder_url": "Url",
"profile_placeholder_logoUrl": "LogoUrl"
}
Loading