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
3 changes: 1 addition & 2 deletions src/components/App/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ const App = () => {
<Route exact path="/advanced" element={<Advanced />} />
<Route exact path="/generate" element={<Generate />} />
<Route exact path="/advisor" element={<Advisor />} />
{/* eslint-disable-next-line no-underscore-dangle */}
{window.__TAURI__ ? (<Route exact path="/vault" element={<Vault />} />) : null}
<Route exact path="/vault" element={<Vault />} />
<Route exact path="/settings" element={<Settings />} />
<Route exact path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
Expand Down
39 changes: 18 additions & 21 deletions src/components/ClippedDrawer/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,30 +149,27 @@ const ClippedDrawer = () => {
{textVisible ? <ListItemText primary={language.advisor} /> : null}
</ListItemButton>
</ListItem>
{/* eslint-disable-next-line no-underscore-dangle */}
{window.__TAURI__ ? (
<ListItem disablePadding sx={{ display: textVisible ? 'block' : null }}>
<ListItemButton
selected={pageIndex === 4}
onClick={() => navigate('/vault')}
<ListItem disablePadding sx={{ display: textVisible ? 'block' : null }}>
<ListItemButton
selected={pageIndex === 4}
onClick={() => navigate('/vault')}
sx={{
minHeight: 48,
justifyContent: textVisible ? 'initial' : 'center',
px: 2.5,
}}
>
<ListItemIcon
sx={{
minHeight: 48,
justifyContent: textVisible ? 'initial' : 'center',
px: 2.5,
minWidth: textVisible ? null : 0,
mr: textVisible ? null : 'auto',
}}
>
<ListItemIcon
sx={{
minWidth: textVisible ? null : 0,
mr: textVisible ? null : 'auto',
}}
>
<FolderIcon />
</ListItemIcon>
{textVisible ? <ListItemText primary={language.vault} /> : null}
</ListItemButton>
</ListItem>
) : null}
<FolderIcon />
</ListItemIcon>
{textVisible ? <ListItemText primary={language.vault} /> : null}
</ListItemButton>
</ListItem>
</List>
<Divider />
<List>
Expand Down
74 changes: 74 additions & 0 deletions src/components/SelectFileDialog/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useState } from 'react';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';

const SelectFileDialog = ({
open, onClose, onAccept, selectFileLabel, cancelLabel, acceptLabel,
}) => {
const [data, setData] = useState(null);

/**
* Close the dialog
*/
const handleClose = () => {
setData(null);
if (onClose) {
onClose();
}
};

const handleFileChange = (e) => {
e.preventDefault();
const reader = new FileReader();
reader.onload = async (ev) => {
const text = (ev.target.result);
setData(text);
};
reader.readAsText(e.target.files[0]);
};

/**
* Accept the file
*/
const accept = () => {
if (onAccept && data && data.length > 0) {
onAccept(data);
}
handleClose();
};

return (
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{selectFileLabel}</DialogTitle>
<DialogContent>
<TextField
type="file"
onChange={handleFileChange}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>
{cancelLabel}
</Button>
<Button
onClick={accept}
autoFocus
disabled={!data || data.length === 0}
>
{acceptLabel}
</Button>
</DialogActions>
</Dialog>
);
};

export default SelectFileDialog;
3 changes: 2 additions & 1 deletion src/languages/de_de.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "Passwort bearbeiten",
"close": "Schließen",
"copy": "Kopieren",
"createOrOpenVault": "Erstellen oder öffnen Sie einen Tresor"
"createOrOpenVault": "Erstellen oder öffnen Sie einen Tresor",
"selectFile": "Datei auswählen"
}
3 changes: 2 additions & 1 deletion src/languages/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "Edit password",
"close": "Close",
"copy": "Copy",
"createOrOpenVault": "Create or open a vault"
"createOrOpenVault": "Create or open a vault",
"selectFile": "Select file"
}
3 changes: 2 additions & 1 deletion src/languages/fr_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "Modifier le mot de passe",
"close": "Fermer",
"copy": "Copier",
"createOrOpenVault": "Créer ou ouvrir un coffre-fort"
"createOrOpenVault": "Créer ou ouvrir un coffre-fort",
"selectFile": "Sélectionner un fichier"
}
3 changes: 2 additions & 1 deletion src/languages/jp_jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "パスワードを編集する",
"close": "閉じる",
"copy": "コピー",
"createOrOpenVault": "金庫を作成または開く"
"createOrOpenVault": "金庫を作成または開く",
"selectFile": "ファイルを選択"
}
3 changes: 2 additions & 1 deletion src/languages/nl_nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "Wachtwoord bewerken",
"close": "Sluiten",
"copy": "Kopiëren",
"createOrOpenVault": "Maak een nieuwe kluis of open een bestaande kluis"
"createOrOpenVault": "Maak een nieuwe kluis of open een bestaande kluis",
"selectFile": "Selecteer een bestand"
}
3 changes: 2 additions & 1 deletion src/languages/ru_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "Изменить пароль",
"close": "Закрыть",
"copy": "Копировать",
"createOrOpenVault": "Создать или открыть сейф"
"createOrOpenVault": "Создать или открыть сейф",
"selectFile": "Выбрать файл"
}
3 changes: 2 additions & 1 deletion src/languages/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"editPassword": "编辑密码",
"close": "关闭",
"copy": "复制",
"createOrOpenVault": "创建或打开保险库"
"createOrOpenVault": "创建或打开保险库",
"selectFile": "选择文件"
}
92 changes: 77 additions & 15 deletions src/routes/Vault/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import VaultCard from '../../components/VaultCard';
import CreatePasswordDialog from '../../components/CreatePasswordDialog';
import EditPasswordDialog from '../../components/EditPasswordDialog';
import EncryptionKeyDialog from '../../components/EncryptionKeyDialog';
import SelectFileDialog from '../../components/SelectFileDialog';

const Vault = () => {
const [state, d1] = useContext(MainContext);
Expand All @@ -35,21 +36,46 @@ const Vault = () => {

const [phrase, setPhrase] = useState('');
const [search, setSearch] = useState('');
const [editPasswordId, setEditPasswordId] = useState(null);
const [keyAction, setKeyAction] = useState(null);

const [keyDialogOpen, setKeyDialogOpen] = useState(false);
const [createPasswordDialogOpen, setCreatePasswordDialogOpen] = useState(false);
const [editPasswordDialogOpen, setEditPasswordDialogOpen] = useState(false);
const [editPasswordId, setEditPasswordId] = useState(null);
const [keyAction, setKeyAction] = useState(null);
const [selectFileOpen, setSelectFileOpen] = useState(false);

/**
* Download a file
* @param data The data that needs to be saved
*/
const downloadFile = (data) => {
const blob = new Blob([data]);
const href = URL.createObjectURL(blob);

const link = document.createElement('a');
link.href = href;
link.download = 'vault';
document.body.appendChild(link);
link.click();

document.body.removeChild(link);
URL.revokeObjectURL(href);
};

/**
* Save the vault
*/
const saveVault = async () => {
try {
const path = await save();
if (path && path.length > 0) {
const encVault = CryptoJS.AES.encrypt(JSON.stringify(vault), phrase).toString();
await invoke('save_string_to_disk', { content: encVault, path });
const encVault = CryptoJS.AES.encrypt(JSON.stringify(vault), phrase).toString();
// eslint-disable-next-line no-underscore-dangle
if (window.__TAURI__) {
const path = await save();
if (path && path.length > 0) {
await invoke('save_string_to_disk', { content: encVault, path });
}
} else {
downloadFile(encVault);
}
} catch (e) {
d1(setError(e.toString()));
Expand All @@ -63,22 +89,45 @@ const Vault = () => {
*/
const openVaultDetails = async (decryptionKey) => {
try {
const path = await open({
multiple: false,
});
if (path && path.length > 0) {
const res = await invoke('read_string_from_file', { path });
// eslint-disable-next-line no-underscore-dangle
if (window.__TAURI__) {
const path = await open({
multiple: false,
});
if (path && path.length > 0) {
const res = await invoke('read_string_from_file', { path });

const bytes = CryptoJS.AES.decrypt(res.toString(), decryptionKey);
const originalText = bytes.toString(CryptoJS.enc.Utf8);
const bytes = CryptoJS.AES.decrypt(res.toString(), decryptionKey);
const originalText = bytes.toString(CryptoJS.enc.Utf8);

d3(setVault(JSON.parse(originalText)));
d3(setVault(JSON.parse(originalText)));
}
} else {
setSelectFileOpen(true);
}
} catch (e) {
d1(setError(e.toString()));
}
};

/**
* Open vault from raw data
* @param data The raw data
* @returns {Promise<void>}
*/
const openVaultFromData = async (data) => {
if (data && data.length > 0) {
try {
const bytes = CryptoJS.AES.decrypt(data.toString(), phrase);
const originalText = bytes.toString(CryptoJS.enc.Utf8);

d3(setVault(JSON.parse(originalText)));
} catch (e) {
d1(setError(e.toString()));
}
}
};

/**
* Open a password URL
* @param url The URL that needs to be opened
Expand Down Expand Up @@ -119,7 +168,12 @@ const Vault = () => {
const copyToClipboard = async (id) => {
const { password } = vault.find((p) => p.id === id);
try {
await writeText(password);
// eslint-disable-next-line no-underscore-dangle
if (window.__TAURI__) {
await writeText(password);
} else {
await navigator.clipboard.writeText(password);
}
} catch (e) {
d1(setError(e.toString()));
}
Expand Down Expand Up @@ -375,6 +429,14 @@ const Vault = () => {
data={toEdit}
/>
) : null}
<SelectFileDialog
open={selectFileOpen}
onClose={() => setSelectFileOpen(false)}
onAccept={openVaultFromData}
selectFileLabel={language.selectFile}
cancelLabel={language.cancel}
acceptLabel={language.ok}
/>
</Container>
);
};
Expand Down