diff --git a/export.html b/export.html index 62f7517..c1e2c14 100644 --- a/export.html +++ b/export.html @@ -9,6 +9,7 @@ + @@ -22,15 +23,18 @@
@@ -87,7 +92,7 @@

Passky

- Backup + Backup
@@ -97,7 +102,7 @@

Passky

- Export + Export
@@ -117,7 +122,7 @@

Lastpass

- Import + Import
@@ -127,7 +132,7 @@

Lastpass

- Export + Export
@@ -147,7 +152,7 @@

Bitwarden

- Import + Import @@ -161,23 +166,23 @@

Dashline

@@ -191,23 +196,23 @@

1Password

@@ -221,23 +226,23 @@

Keeper

@@ -251,23 +256,23 @@

Nordpass

@@ -288,20 +293,14 @@

Nordpass

-

- Delete account -

+

-

- Are you sure you want to delete your account? All of your data will be permanently removed from server forever. This action cannot be undone. -

+

- + diff --git a/index.html b/index.html index 1271a80..b026f85 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,7 @@ + @@ -71,7 +72,7 @@

Sign in - + Don't have account yet? Sign up here.

diff --git a/js/default-functions.js b/js/default-functions.js index 3b691e4..aad03ac 100644 --- a/js/default-functions.js +++ b/js/default-functions.js @@ -50,17 +50,32 @@ function toggleMenu(){ } function changeTheme(){ - if(localStorage.theme == 0){ - document.getElementById("css-theme").href = "css/themes/light.css"; - document.getElementById("theme-link").innerText = "Theme (Light)"; - document.getElementById("theme-link-mobile").innerText = "Theme (Light)"; - localStorage.theme = 1; - }else{ - document.getElementById("css-theme").href = "css/themes/dark.css"; - document.getElementById("theme-link").innerText = "Theme (Dark)"; - document.getElementById("theme-link-mobile").innerText = "Theme (Dark)"; - localStorage.theme = 0; + switch(localStorage.theme){ + case "dark": + document.getElementById("css-theme").href = "css/themes/light.css"; + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + localStorage.theme = "light"; + break; + default: + document.getElementById("css-theme").href = "css/themes/dark.css"; + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + localStorage.theme = "dark"; + break; + } +} + +function changeLanguage(){ + switch(localStorage.lang){ + case "en": + localStorage.lang = "sl"; + break; + default: + localStorage.lang = "en"; + break; } + location.reload(); } function copyToClipboard(text){ @@ -80,33 +95,6 @@ function copyToClipboard(text){ document.body.removeChild(textArea); } -const errors = { - "0": "Successful", - "1": "Username is invalid!", - "2": "Password is incorrect!", - "3": "Something went wrong while inserting data to database!", - "4": "Username is already registered!", - "5": "Password must be between 8 and 255 characters long and have at least one letter, one number and one special character!", - "6": "Email is invalid!", - "7": "Username doesn't exist!", - "8": "You don't have any saved password.", - "9": "Domain is invalid!", - "10": "User does not own this password!", - "11": "Something went wrong while deleting data from database!", - "12": "Username must be between 6 and 30 characters long and can only contains letters, numbers and dots!", - "13": "Something went wrong while updating data in database!", - "14": "Json is invalid!", - "15": "This server can't accept more users!", - "16": "You have reached maximum amount of stored passwords!", - "400": "Action was not provided in POST!", - "401": "Action is invalid!", - "403": "You didn't provide all required values in POST.", - "404": "Can't connect into API.", - "429": "You are sending too many requests! Please wait some time before executing this action.", - "505": "Something went wrong while connecting to database!", - "999": "You don't have permission to use this endpoint." -} - function downloadTxt(exportTxt, exportName){ let dataStr = "data:text/plain;charset=utf-8," + encodeURIComponent(exportTxt); let downloadAnchorNode = document.createElement('a'); diff --git a/js/export.js b/js/export.js index 5be9b66..b3d3b37 100644 --- a/js/export.js +++ b/js/export.js @@ -1,5 +1,54 @@ check_login(); +document.getElementById("passwords-link").innerText = lang[localStorage.lang]["passwords"]; +document.getElementById("import-export-link").innerText = lang[localStorage.lang]["import_export"]; +document.getElementById("signout-link").innerText = lang[localStorage.lang]["signout"]; + +document.getElementById("passwords-link-mobile").innerText = lang[localStorage.lang]["passwords"]; +document.getElementById("import-export-link-mobile").innerText = lang[localStorage.lang]["import_export"]; +document.getElementById("signout-link-mobile").innerText = lang[localStorage.lang]["signout"]; + +switch(localStorage.theme){ + case "light": + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + break; + default: + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + break; +} + +switch(localStorage.lang){ + case "sl": + document.getElementById("lang-link").innerText = "Language (Slovenian)"; + document.getElementById("lang-link-mobile").innerText = "Language (Slovenian)"; + break; + default: + document.getElementById("lang-link").innerText = "Language (English)"; + document.getElementById("lang-link-mobile").innerText = "Language (English)"; + break; +} + +document.getElementById("passky-backup-btn-text").innerText = lang[localStorage.lang]["backup"]; + +document.getElementById("passky-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("lastpass-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("bitwarden-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("dashline-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("onepassword-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("keeper-import-btn-text").innerText = lang[localStorage.lang]["import"]; +document.getElementById("nordpass-import-btn-text").innerText = lang[localStorage.lang]["import"]; + +document.getElementById("passky-export-btn-text").innerText = lang[localStorage.lang]["export"]; +document.getElementById("lastpass-export-btn-text").innerText = lang[localStorage.lang]["export"]; +document.getElementById("dashline-export-btn-text").innerText = lang[localStorage.lang]["export"]; +document.getElementById("onepassword-export-btn-text").innerText = lang[localStorage.lang]["export"]; +document.getElementById("keeper-export-btn-text").innerText = lang[localStorage.lang]["export"]; +document.getElementById("nordpass-export-btn-text").innerText = lang[localStorage.lang]["export"]; + +document.getElementById("dialog-button-cancel").innerText = lang[localStorage.lang]["cancel"]; + function import_passky(){ check_login(); @@ -196,7 +245,7 @@ function import_data(passwords){ if(xhr.readyState === 4){ if(xhr.status != 200){ - changeDialog(0, "Server is unreachable!"); + changeDialog(0, lang[localStorage.lang]["server_unreachable"]); show('dialog'); return; } @@ -204,23 +253,23 @@ function import_data(passwords){ var json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - changeDialog(0, "Server is unreachable!"); + changeDialog(0, lang[localStorage.lang]["server_unreachable"]); show('dialog'); return; } if(json['error'] != 0){ - changeDialog(0, errors[json['error']]); + changeDialog(0, errors[localStorage.lang][json['error']]); show('dialog'); return; } if(json['error'] == 0){ if(json['import_error'] == 0){ - changeDialog(3, json['import_success'] + " passwords has been successfully imported!"); + changeDialog(3, lang[localStorage.lang]["import_success"].replace("{success_number}", json['import_success'])); show('dialog'); }else{ - changeDialog(3, json['import_success'] + " passwords has been successfully imported, but " + json['import_error'] + " passwords has not been imported!"); + changeDialog(3, lang[localStorage.lang]["import_errors"].replace("{success_number}", json['import_success']).replace("{error_number}", json['import_error'])); show('dialog'); } } @@ -240,19 +289,19 @@ function changeDialog(style, text, text2){ document.getElementById('dialog-text').innerHTML = ""; document.getElementById('dialog-button').className = "primaryButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Import"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["import"]; switch(text){ case 0: - document.getElementById('dialog-title').innerText = "Import from Passky"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["import_from"].replace("{name}","Passky"); document.getElementById('dialog-button').onclick = () => import_passky(); break; case 1: - document.getElementById('dialog-title').innerText = "Import from Lastpass"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["import_from"].replace("{name}","Lastpass"); document.getElementById('dialog-button').onclick = () => import_lastpass(); break; case 2: - document.getElementById('dialog-title').innerText = "Import from Bitwarden"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["import_from"].replace("{name}","Bitwarden"); document.getElementById('dialog-button').onclick = () => import_bitwarden(); break; } @@ -262,11 +311,11 @@ function changeDialog(style, text, text2){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "ERROR"; - document.getElementById('dialog-text').innerText = "Data in import is invalid!"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["error"]; + document.getElementById('dialog-text').innerText = lang[localStorage.lang]["import_invalid"]; document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Try again"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["try_again"]; document.getElementById('dialog-button').onclick = () => changeDialog(text, text2); break; case 3: @@ -274,11 +323,11 @@ function changeDialog(style, text, text2){ document.getElementById('dialog-icon').className = "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "SUCCESS"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["success"]; document.getElementById('dialog-text').innerText = text; document.getElementById('dialog-button').className = "successButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Okay"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["okay"]; document.getElementById('dialog-button').onclick = () => refreshPasswords(); break; default: @@ -286,11 +335,11 @@ function changeDialog(style, text, text2){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "ERROR"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["error"]; document.getElementById('dialog-text').innerText = text; document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Okay"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["okay"]; document.getElementById('dialog-button').onclick = () => hide('dialog'); break; } @@ -312,6 +361,14 @@ document.getElementById("theme-link-mobile").addEventListener("click", () => { changeTheme(); }); +document.getElementById("lang-link").addEventListener("click", () => { + changeLanguage(); +}); + +document.getElementById("lang-link-mobile").addEventListener("click", () => { + changeLanguage(); +}); + document.getElementById("main-menu-toggle-btn").addEventListener("click", () => { toggleMenu(); }); diff --git a/js/header.js b/js/header.js index 75ac8c2..f0c239e 100644 --- a/js/header.js +++ b/js/header.js @@ -1,7 +1,11 @@ -if(localStorage.theme == null || typeof(localStorage.theme) == 'undefined') localStorage.theme = 0; +if(localStorage.theme == null || typeof(localStorage.theme) == 'undefined') localStorage.theme = "dark"; +if(localStorage.lang == null || typeof(localStorage.lang) == 'undefined') localStorage.lang = "en"; -if(localStorage.theme == 0){ - document.getElementById("css-theme").href = "css/themes/dark.css"; -}else{ - document.getElementById("css-theme").href = "css/themes/light.css"; +if(!(localStorage.theme == "dark" || localStorage.theme == "light")) localStorage.theme = "dark"; +if(!(localStorage.lang == "en" || localStorage.lang == "sl")) localStorage.lang = "en"; + +switch(localStorage.theme){ + case "light": + document.getElementById("css-theme").href = "css/themes/light.css"; + break; } \ No newline at end of file diff --git a/js/lang.js b/js/lang.js new file mode 100644 index 0000000..a64674e --- /dev/null +++ b/js/lang.js @@ -0,0 +1,165 @@ +const lang = { + "en": { + "server": "Server", + "website": "Website", + "username": "Username", + "email": "Email", + "password": "Password", + "signin": "Sign in", + "signup": "Sign up", + "signout": "Sign out", + "okay": "Okay", + "add": "Add", + "change": "Change", + "use": "Use", + "copy": "Copy", + "cancel": "Cancel", + "try_again": "Try again", + "success": "SUCCESS", + "error": "ERROR", + "delete": "Delete", + "import": "Import", + "import_from": "Import from {name}", + "import_invalid": "Data in import is invalid!", + "import_success": "{success_number} passwords has been successfully imported!", + "import_errors": "{success_number} passwords has been successfully imported, but {error_number} passwords has not been imported!", + "backup": "Backup", + "export": "Export", + "passwords": "Passwords", + "import_export": "Import & Export", + "theme": "Theme", + "search": "Search", + "length": "Length", + "add_password": "Add password", + "add_password_success": "Password has been added successfully", + "change_password_success": "Password has been changed successfully", + "remove_password_success": "Password has been removed successfully", + "edit_password": "Edit password", + "password_generator": "Password Generator", + "delete_password": "Delete password", + "delete_password_confirmation": "Are you sure you want to delete your password? Your password will be permanently removed from server forever. This action cannot be undone.", + "delete_account": "Delete account", + "delete_account_info": "Once you delete your account, you will lose all data associated with it.", + "delete_account_confirmation": "Are you sure you want to delete your account? All of your data will be permanently removed from server forever. This action cannot be undone.", + "url_invalid": "Server url is invalid!", + "server_unreachable": "Server is unreachable!", + "registration_completed": "Registration is completed!", + "dont_have_account_link": "Don't have account yet? Sign up here.", + "already_have_account_link": "Already have account? Sign in here.", + "username_validation": "Username must be between 3 and 255 character long and can't contain spaces!", + "username_validation2": "Username can't contains provided special characters: ' \" \\", + "password_validation": "Password must be between 8 and 255 character long and can't contain spaces!", + "password_validation2": "Password can't contains provided special characters: ' \" \\", + "website_validation": "Website much be between 5 and 255 character long and can't contain spaces!", + "website_validation2": "Website can't contains provided special characters: ' \" \\" + }, + "sl": { + "server": "Strežnik", + "website": "Spletna stran", + "username": "Uporabniško ime", + "email": "E-naslov", + "password": "Geslo", + "signin": "Vpis", + "signup": "Prijava", + "signout": "Odjava", + "okay": "Okay", + "add": "Dodaj", + "change": "Spremeni", + "use": "Uporabi", + "copy": "Kopiraj", + "cancel": "Prekliči", + "try_again": "Poskusite znova", + "success": "USPEH", + "error": "NAPAKA", + "delete": "Izbriši", + "import": "Uvozi", + "import_from": "Uvozi iz {name}", + "import_invalid": "Podatki pri uvozu so neveljavni!", + "import_success": "{success_number} gesla so bila uspešno uvožena! ", + "import_errors": "{success_number} gesel je bilo uspešno uvoženih, {error_number} gesel pa ni bilo uvoženih!", + "backup": "Rezerva", + "export": "Izvoz", + "passwords": "Gesla", + "import_export": "Uvoz in Izvoz", + "theme": "Tema", + "search": "Iskanje", + "length": "Dolžina", + "add_password": "Dodaj geslo", + "add_password_success": "Geslo je bilo uspešno dodano", + "change_password_success": "Geslo je bilo uspešno spremenjeno", + "remove_password_success": "Geslo je bilo uspešno odstranjeno", + "edit_password": "Uredi geslo", + "password_generator": "Generator gesel", + "delete_password": "Izbriši geslo", + "delete_password_confirmation": "Ali ste prepričani, da želite izbrisati geslo? Vaše geslo bo za vedno odstranjeno s strežnika. Tega dejanja ni mogoče razveljaviti.", + "delete_account": "Izbriši račun", + "delete_account_info": "Ko izbrišete račun, boste izgubili vse podatke, povezane z njim.", + "delete_account_confirmation": "Ali ste prepričani, da želite izbrisati svoj račun? Vsi vaši podatki bodo za vedno odstranjeni s strežnika. Tega dejanja ni mogoče razveljaviti.", + "url_invalid": "URL strežnika ni veljaven!", + "server_unreachable": "Strežnik je nedosegljiv!", + "registration_completed": "Registracija je končana!", + "dont_have_account_link": "Še nimate računa? Prijavite se tukaj.", + "already_have_account_link": "Že imate račun? Prijavite se tukaj.", + "username_validation": "Uporabniško ime mora biti dolgo med 3 in 255 znaki in ne sme vsebovati presledkov!", + "username_validation2": "Uporabniško ime ne more vsebovati predvidenih posebnih znakov: ' \" \\", + "password_validation": "Geslo mora biti dolgo med 8 in 255 znaki in ne sme vsebovati presledkov!", + "password_validation2": "Geslo ne more vsebovati predvidenih posebnih znakov: ' \" \\", + "website_validation": "Spletno mesto mora biti dolgo med 5 in 255 znaki in ne sme vsebovati presledkov!", + "website_validation2": "Spletno mesto ne more vsebovati predvidenih posebnih znakov: ' \" \\" + } +} + +const errors = { + "en": { + "0": "Successful", + "1": "Username is invalid!", + "2": "Password is incorrect!", + "3": "Something went wrong while inserting data to database!", + "4": "Username is already registered!", + "5": "Password must be between 8 and 255 characters long and have at least one letter, one number and one special character!", + "6": "Email is invalid!", + "7": "Username doesn't exist!", + "8": "You don't have any saved password.", + "9": "Domain is invalid!", + "10": "User does not own this password!", + "11": "Something went wrong while deleting data from database!", + "12": "Username must be between 6 and 30 characters long and can only contains letters, numbers and dots!", + "13": "Something went wrong while updating data in database!", + "14": "Json is invalid!", + "15": "This server can't accept more users!", + "16": "You have reached maximum amount of stored passwords!", + "400": "Action was not provided in POST!", + "401": "Action is invalid!", + "403": "You didn't provide all required values in POST.", + "404": "Can't connect into API.", + "429": "You are sending too many requests! Please wait some time before executing this action.", + "505": "Something went wrong while connecting to database!", + "999": "You don't have permission to use this endpoint." + }, + "sl": { + "0": "Uspešno", + "1": "Uporabniško ime je neveljavno!", + "2": "Geslo je napačno!", + "3": "Med vstavljanjem podatkov v bazo podatkov je prišlo do napake!", + "4": "Uporabniško ime je že registrirano!", + "5": "Geslo mora biti dolgo med 8 in 255 znaki in mora vsebovati vsaj eno črko, eno številko in en poseben znak!", + "6": "E-pošta je neveljavna!", + "7": "Uporabniško ime ne obstaja!", + "8": "Nimate shranjenega gesla.", + "9": "Domena je neveljavna!", + "10": "Uporabnik ni lastnik tega gesla!", + "11": "Med brisanjem podatkov iz baze podatkov je prišlo do napake!", + "12": "Uporabniško ime mora biti dolgo med 6 in 30 znakov in lahko vsebuje samo črke, številke in pike!", + "13": "Med posodabljanjem podatkov v bazi je prišlo do napake!", + "14": "Json je neveljaven!", + "15": "Ta strežnik ne more sprejeti več uporabnikov!", + "16": "Dosegli ste največjo količino shranjenih gesel!", + "400": "Akcija ni bila zagotovljena v POST-u!", + "401": "Dejanje je neveljavno!", + "403": "V POST niste navedli vseh zahtevanih vrednosti. ", + "404": "Ne morem se povezati z API-jem.", + "429": "Pošiljate preveč zahtev! Počakajte nekaj časa, preden izvedete to dejanje. ", + "505": "Med povezovanjem z bazo podatkov je prišlo do napake!", + "999": "Nimate dovoljenja za uporabo te točke." + } +} \ No newline at end of file diff --git a/js/login.js b/js/login.js index cb1d48f..562933f 100644 --- a/js/login.js +++ b/js/login.js @@ -3,6 +3,15 @@ if(localStorage.url !== null && typeof(localStorage.url) !== 'undefined' && loca if(localStorage.url !== null && typeof(localStorage.url) !== 'undefined') document.getElementById('passky-server').value = localStorage.url; if(localStorage.username !== null && typeof(localStorage.username) !== 'undefined') document.getElementById('username').value = localStorage.username; +//Languages +document.getElementById("passky-server").placeholder = lang[localStorage.lang]["server"]; +document.getElementById("username").placeholder = lang[localStorage.lang]["username"]; +document.getElementById("password").placeholder = lang[localStorage.lang]["password"]; +document.getElementById("btn_signin").innerText = lang[localStorage.lang]["signin"]; +document.getElementById("error-dialog-modal-title").innerText = lang[localStorage.lang]["error"]; +document.getElementById("dont_have_account_link").innerText = lang[localStorage.lang]["dont_have_account_link"]; +document.getElementById("error-dialog-okay").innerText = lang[localStorage.lang]["okay"]; + document.getElementById("login_form").addEventListener("submit", e => { e.preventDefault(); onBtnClick(); @@ -21,19 +30,19 @@ function onBtnClick(){ if(url.length == 0 || username.length == 0 || password.length == 0) return; if(!/^[a-z0-9.]{6,30}$/i.test(username)){ - setText('error-dialog-modal-text', "Username must be between 6 and 30 characters long and can only contains letters, numbers and dots!"); + setText('error-dialog-modal-text', errors[localStorage.lang]["12"]); show('error-dialog'); return; } if(!/^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,255}$/i.test(password)){ - setText('error-dialog-modal-text', "Password must be between 8 and 255 characters long and have at least one letter, one number and one special character!"); + setText('error-dialog-modal-text', errors[localStorage.lang]["5"]); show('error-dialog'); return; } if(!validURL(url)){ - setText('error-dialog-modal-text', "Server url is invalid!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["url_invalid"]); show('error-dialog'); return; } @@ -49,20 +58,20 @@ function onBtnClick(){ if(xhr.readyState === 4){ if(xhr.status != 200){ - setText('error-dialog-modal-text', "Server is unreachable!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["server_unreachable"]); show('error-dialog'); return; } var json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - setText('error-dialog-modal-text', "Server is unreachable!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["server_unreachable"]); show('error-dialog'); return; } if(json['error'] != 0 && json['error'] != 8){ - setText('error-dialog-modal-text', errors[json['error']]); + setText('error-dialog-modal-text', errors[localStorage.lang][json['error']]); show('error-dialog'); return; } diff --git a/js/passwords.js b/js/passwords.js index b801080..05a29f7 100644 --- a/js/passwords.js +++ b/js/passwords.js @@ -1,3 +1,42 @@ +document.getElementById("passwords-link").innerText = lang[localStorage.lang]["passwords"]; +document.getElementById("import-export-link").innerText = lang[localStorage.lang]["import_export"]; +document.getElementById("signout-link").innerText = lang[localStorage.lang]["signout"]; + +document.getElementById("passwords-link-mobile").innerText = lang[localStorage.lang]["passwords"]; +document.getElementById("import-export-link-mobile").innerText = lang[localStorage.lang]["import_export"]; +document.getElementById("signout-link-mobile").innerText = lang[localStorage.lang]["signout"]; + +switch(localStorage.theme){ + case "light": + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Light)"; + break; + default: + document.getElementById("theme-link").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + document.getElementById("theme-link-mobile").innerText = lang[localStorage.lang]["theme"] + " (Dark)"; + break; +} + +switch(localStorage.lang){ + case "sl": + document.getElementById("lang-link").innerText = "Language (Slovenian)"; + document.getElementById("lang-link-mobile").innerText = "Language (Slovenian)"; + break; + default: + document.getElementById("lang-link").innerText = "Language (English)"; + document.getElementById("lang-link-mobile").innerText = "Language (English)"; + break; +} + +document.getElementById("search").placeholder = lang[localStorage.lang]["search"]; +document.getElementById("add-password-btn").innerText = lang[localStorage.lang]["add_password"]; + +document.getElementById("delete-account-title").innerText = lang[localStorage.lang]["delete_account"]; +document.getElementById("delete-account-text").innerText = lang[localStorage.lang]["delete_account_info"]; +document.getElementById("delete-account-btn").innerText = lang[localStorage.lang]["delete_account"]; + +document.getElementById("dialog-button-cancel").innerText = lang[localStorage.lang]["cancel"]; + function displayPasswords(){ let html_passwords = ""; @@ -53,9 +92,7 @@ function displayPasswords(){ show('dialog'); }); } - } - } displayPasswords(); @@ -94,6 +131,14 @@ document.getElementById("theme-link-mobile").addEventListener("click", () => { changeTheme(); }); +document.getElementById("lang-link").addEventListener("click", () => { + changeLanguage(); +}); + +document.getElementById("lang-link-mobile").addEventListener("click", () => { + changeLanguage(); +}); + document.getElementById("main-menu-toggle-btn").addEventListener("click", () => { toggleMenu(); }); @@ -152,11 +197,11 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "Delete account"; - document.getElementById('dialog-text').innerText = "Are you sure you want to delete your account? All of your data will be permanently removed from server forever. This action cannot be undone."; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["delete_account"]; + document.getElementById('dialog-text').innerText = lang[localStorage.lang]["delete_account_confirmation"]; document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Delete"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["delete"]; document.getElementById('dialog-button').onclick = () => deleteAccount(); break; case 2: @@ -164,11 +209,11 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "ERROR"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["error"]; document.getElementById('dialog-text').innerText = text; document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Try again"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["try_again"]; document.getElementById('dialog-button').onclick = () => changeDialog(0); break; case 3: @@ -176,15 +221,15 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "SUCCESS"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["success"]; - let message = "Password has been added successfully"; + let message = lang[localStorage.lang]["add_password_success"]; switch(text){ case 1: - message = "Password has been changed successfully"; + message = lang[localStorage.lang]["change_password_success"]; break; case 2: - message = "Password has been removed successfully"; + message = lang[localStorage.lang]["remove_password_success"]; break; } document.getElementById('dialog-text').innerText = message; @@ -192,7 +237,7 @@ function changeDialog(style, text){ document.getElementById('dialog-button-cancel').style.display = 'none'; document.getElementById('dialog-button').className = "successButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Okay"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["okay"]; document.getElementById('dialog-button').onclick = () => refreshPasswords(); break; case 4: @@ -202,12 +247,12 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "Edit password"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["edit_password"]; - document.getElementById('dialog-text').innerHTML = "
"; + document.getElementById('dialog-text').innerHTML = "
"; document.getElementById('dialog-button').className = "primaryButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Change"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["change"]; document.getElementById('dialog-button').onclick = () => editPassword(e_data[0]); document.getElementById('btn-password-generator').onclick = () => changeDialog(5, text); @@ -223,9 +268,9 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "Password Generator"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["password_generator"]; - document.getElementById('dialog-text').innerHTML = "
A-Z
0-9
!@#$%?&*
Length
"; + document.getElementById('dialog-text').innerHTML = "
A-Z
0-9
!@#$%?&*
" + lang[localStorage.lang]["length"] + "
"; document.getElementById('dialog-button').className = "primaryButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; @@ -251,16 +296,16 @@ function changeDialog(style, text){ } if(pg_data[0] == null){ - document.getElementById('dialog-button').innerText = "Copy"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["copy"]; document.getElementById('dialog-button').onclick = () => copyToClipboard(document.getElementById('generated-password').innerText); }else if(pg_data[0] == "-1"){ - document.getElementById('dialog-button').innerText = "Use"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["use"]; document.getElementById('dialog-button').onclick = () => { text = pg_data[0] + " " + pg_data[1] + " " + pg_data[2] + " " + document.getElementById('generated-password').innerText; changeDialog(0, text); } }else{ - document.getElementById('dialog-button').innerText = "Use"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["use"]; document.getElementById('dialog-button').onclick = () => { text = pg_data[0] + " " + pg_data[1] + " " + pg_data[2] + " " + document.getElementById('generated-password').innerText; changeDialog(4, text); @@ -276,11 +321,11 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "Delete password"; - document.getElementById('dialog-text').innerText = "Are you sure you want to delete your password? Your password will be permanently removed from server forever. This action cannot be undone."; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["delete_password"]; + document.getElementById('dialog-text').innerText = lang[localStorage.lang]["delete_password_confirmation"]; document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Delete"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["delete"]; document.getElementById('dialog-button').onclick = () => deletePassword(text); break; default: @@ -288,12 +333,12 @@ function changeDialog(style, text){ document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"; document.getElementById('dialog-icon').innerHTML = ""; - document.getElementById('dialog-title').innerText = "Add password"; + document.getElementById('dialog-title').innerText = lang[localStorage.lang]["add_password"]; - document.getElementById('dialog-text').innerHTML = "
"; + document.getElementById('dialog-text').innerHTML = "
"; document.getElementById('dialog-button').className = "primaryButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm"; - document.getElementById('dialog-button').innerText = "Add"; + document.getElementById('dialog-button').innerText = lang[localStorage.lang]["add"]; document.getElementById('dialog-button').onclick = () => addPassword(); if(text != null){ @@ -317,6 +362,8 @@ function changeDialog(style, text){ } function addPassword(){ + check_login(); + const website = document.getElementById("website").value; const username = document.getElementById("username").value; let password = document.getElementById("password").value; @@ -324,37 +371,32 @@ function addPassword(){ if(website.length == 0 || username.length == 0 || password.length == 0) return; if(!(username.length >= 3 && username.length <= 255) || username.includes(" ")){ - changeDialog(2, "Username must be between 3 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["username_validation"]); return; } if(username.includes("'") || username.includes('"') || username.includes("\\")){ - changeDialog(2, "Username can't contains provided special characters: ' \" \\"); + changeDialog(2, lang[localStorage.lang]["username_validation2"]); return; } if(!(password.length >= 8 && password.length <= 255) || password.includes(" ")){ - changeDialog(2, "Password must be between 8 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["password_validation"]); return; } if(password.includes("'") || password.includes('"') || password.includes("\\")){ - changeDialog(2, "Password can't contains provided special characters: ' \" \\"); + changeDialog(2, lang[localStorage.lang]["password_validation2"]); return; } if(!(website.length >= 5 && website.length <= 255) || website.includes(" ")){ - changeDialog(2, "Website much be between 5 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["website_validation"]); return; } if(website.includes("'") || website.includes('"') || website.includes("\\")){ - changeDialog(2, "Website can't contains provided special characters: ' \" \\"); - return; - } - - if(localStorage.url === null || typeof(localStorage.url) === 'undefined' || localStorage.username === null || typeof(localStorage.username) === 'undefined' || localStorage.password === null || typeof(localStorage.password) === 'undefined'){ - changeDialog(2, "Session has expired please sign in again!"); + changeDialog(2, lang[localStorage.lang]["website_validation2"]); return; } @@ -371,19 +413,19 @@ function addPassword(){ if(xhr.readyState === 4){ if(xhr.status != 200){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } const json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } if(json['error'] != 0){ - changeDialog(2, errors[json['error']]); + changeDialog(2, errors[localStorage.lang][json['error']]); return; } @@ -395,6 +437,8 @@ function addPassword(){ } function editPassword(password_id){ + check_login(); + const website = document.getElementById("website").value; const username = document.getElementById("username").value; let password = document.getElementById("password").value; @@ -402,37 +446,32 @@ function editPassword(password_id){ if(password_id.length == 0 || website.length == 0 || username.length == 0 || password.length == 0) return; if(!(username.length >= 3 && username.length <= 255) || username.includes(" ")){ - changeDialog(2, "Username must be between 3 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["username_validation"]); return; } if(username.includes("'") || username.includes('"') || username.includes("\\")){ - changeDialog(2, "Username can't contains provided special characters: ' \" \\"); + changeDialog(2, lang[localStorage.lang]["username_validation2"]); return; } if(!(password.length >= 8 && password.length <= 255) || password.includes(" ")){ - changeDialog(2, "Password must be between 8 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["password_validation"]); return; } if(password.includes("'") || password.includes('"') || password.includes("\\")){ - changeDialog(2, "Password can't contains provided special characters: ' \" \\"); + changeDialog(2, lang[localStorage.lang]["password_validation2"]); return; } if(!(website.length >= 5 && website.length <= 255) || website.includes(" ")){ - changeDialog(2, "Website much be between 5 and 255 character long and can't contain spaces!"); + changeDialog(2, lang[localStorage.lang]["website_validation"]); return; } if(website.includes("'") || website.includes('"') || website.includes("\\")){ - changeDialog(2, "Website can't contains provided special characters: ' \" \\"); - return; - } - - if(localStorage.url === null || typeof(localStorage.url) === 'undefined' || localStorage.username === null || typeof(localStorage.username) === 'undefined' || localStorage.password === null || typeof(localStorage.password) === 'undefined'){ - changeDialog(2, "Session has expired please sign in again!"); + changeDialog(2, lang[localStorage.lang]["website_validation2"]); return; } @@ -449,19 +488,19 @@ function editPassword(password_id){ if(xhr.readyState === 4){ if(xhr.status != 200){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } const json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } if(json['error'] != 0){ - changeDialog(2, errors[json['error']]); + changeDialog(2, errors[localStorage.lang][json['error']]); return; } @@ -484,19 +523,19 @@ function deletePassword(password_id){ if(xhr.readyState === 4){ if(xhr.status != 200){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } const json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - changeDialog(2, "Server is unreachable!"); + changeDialog(2, lang[localStorage.lang]["server_unreachable"]); return; } if(json['error'] != 0){ - changeDialog(2, errors[json['error']]); + changeDialog(2, errors[localStorage.lang][json['error']]); return; } diff --git a/js/register.js b/js/register.js index c79f1d0..d47a8cb 100644 --- a/js/register.js +++ b/js/register.js @@ -1,5 +1,14 @@ if(localStorage.url !== null && typeof(localStorage.url) !== 'undefined') document.getElementById('passky-server').value = localStorage.url; +document.getElementById("passky-server").placeholder = lang[localStorage.lang]["server"]; +document.getElementById("username").placeholder = lang[localStorage.lang]["username"]; +document.getElementById("email").placeholder = lang[localStorage.lang]["email"]; +document.getElementById("password").placeholder = lang[localStorage.lang]["password"]; +document.getElementById("btn-dialog").innerText = lang[localStorage.lang]["okay"]; +document.getElementById("error-dialog-modal-title").innerText = lang[localStorage.lang]["error"]; +document.getElementById("btn_signup").innerText = lang[localStorage.lang]["signup"]; +document.getElementById("already_have_account_link").innerText = lang[localStorage.lang]["already_have_account_link"]; + document.getElementById("signup-form").addEventListener("submit", e => { e.preventDefault(); onBtnClick(); @@ -19,25 +28,25 @@ function onBtnClick(){ if(url.length == 0 || username.length == 0 || email.length == 0 || password.length == 0) return; if(!/^[a-z0-9.]{6,30}$/i.test(username)){ - setText('error-dialog-modal-text', "Username must be between 6 and 30 characters long and can only contains letters, numbers and dots!"); + setText('error-dialog-modal-text', errors[localStorage.lang]["12"]); show('error-dialog'); return; } if(!/^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,255}$/i.test(password)){ - setText('error-dialog-modal-text', "Password must be between 8 and 255 characters long and have at least one letter, one number and one special character!"); + setText('error-dialog-modal-text', errors[localStorage.lang]["5"]); show('error-dialog'); return; } if(!validEmail(email)){ - setText('error-dialog-modal-text', "Email is invalid!"); + setText('error-dialog-modal-text', errors[localStorage.lang]["6"]); show('error-dialog'); return; } if(!validURL(url)){ - setText('error-dialog-modal-text', "Server url is invalid!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["url_invalid"]); show('error-dialog'); return; } @@ -53,7 +62,7 @@ function onBtnClick(){ if(xhr.readyState === 4){ if(xhr.status != 200){ - setText('error-dialog-modal-text', "Server is unreachable!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["server_unreachable"]); show('error-dialog'); return; } @@ -61,13 +70,13 @@ function onBtnClick(){ var json = JSON.parse(xhr.responseText); if(typeof json['error'] === 'undefined'){ - setText('error-dialog-modal-text', "Server is unreachable!"); + setText('error-dialog-modal-text', lang[localStorage.lang]["server_unreachable"]); show('error-dialog'); return; } if(json['error'] != 0){ - setText('error-dialog-modal-text', errors[json['error']]); + setText('error-dialog-modal-text', errors[localStorage.lang][json['error']]); show('error-dialog'); return; } @@ -75,8 +84,8 @@ function onBtnClick(){ localStorage.url = url; localStorage.username = username; - setText('error-dialog-modal-title', "SUCCESS"); - setText('error-dialog-modal-text', "Registration is completed!"); + setText('error-dialog-modal-title', lang[localStorage.lang]["success"]); + setText('error-dialog-modal-text', lang[localStorage.lang]["registration_completed"]); document.getElementById('dialog-icon').className = "mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100"; document.getElementById('dialog-icon').innerHTML = ""; document.getElementById('btn-dialog').className = "successButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium sm:text-sm" diff --git a/passwords.html b/passwords.html index b94721f..50d10a1 100644 --- a/passwords.html +++ b/passwords.html @@ -9,6 +9,7 @@ + @@ -23,15 +24,18 @@