Co-authored-by: DemiarUA <demiar97@gmail.com> https://github.com/Lisoveliy/totpfit/pull/1
235 lines
7.5 KiB
JavaScript
235 lines
7.5 KiB
JavaScript
import { getTOTPByLink } from "./utils/queryParser.js";
|
|
import { createTOTPCard } from "./ui/card.js";
|
|
|
|
let _props = null;
|
|
let editingIndex = -1;
|
|
let tempIssuer = "";
|
|
let tempClient = "";
|
|
let errorMessage = "";
|
|
|
|
const colors = {
|
|
bg: "#101010",
|
|
linkBg: "#ffffffc0",
|
|
secondaryBg: "#282828",
|
|
text: "#fafafa",
|
|
alert: "#ad3c23",
|
|
notify: "#555555",
|
|
bigText: "#fafafa",
|
|
};
|
|
|
|
function updateStorage(storage) {
|
|
_props.settingsStorage.setItem("TOTPs", JSON.stringify(storage));
|
|
}
|
|
|
|
function GetTOTPList(storage) {
|
|
return storage.map((element, index) => {
|
|
return createTOTPCard({
|
|
element,
|
|
index,
|
|
storage,
|
|
isEditing: editingIndex === index,
|
|
tempIssuer,
|
|
tempClient,
|
|
onIssuerChange: (val) => {
|
|
tempIssuer = val;
|
|
},
|
|
onClientChange: (val) => {
|
|
tempClient = val;
|
|
},
|
|
onRename: () => {
|
|
editingIndex = index;
|
|
tempIssuer = element.issuer;
|
|
tempClient = element.client;
|
|
updateStorage(storage);
|
|
},
|
|
onSave: () => {
|
|
storage[index].issuer = tempIssuer;
|
|
storage[index].client = tempClient;
|
|
editingIndex = -1;
|
|
updateStorage(storage);
|
|
},
|
|
onDelete: () => {
|
|
storage.splice(index, 1);
|
|
updateStorage(storage);
|
|
},
|
|
onMoveUp: () => {
|
|
if (index > 0) {
|
|
[storage[index], storage[index - 1]] = [
|
|
storage[index - 1],
|
|
storage[index],
|
|
];
|
|
updateStorage(storage);
|
|
}
|
|
},
|
|
onMoveDown: () => {
|
|
if (index < storage.length - 1) {
|
|
[storage[index], storage[index + 1]] = [
|
|
storage[index + 1],
|
|
storage[index],
|
|
];
|
|
updateStorage(storage);
|
|
}
|
|
},
|
|
});
|
|
});
|
|
}
|
|
|
|
AppSettingsPage({
|
|
build(props) {
|
|
_props = props;
|
|
const storage = JSON.parse(
|
|
props.settingsStorage.getItem("TOTPs") ?? "[]",
|
|
);
|
|
const totpEntrys = GetTOTPList(storage);
|
|
const addTOTPsHint =
|
|
storage.length < 1
|
|
? Text(
|
|
{
|
|
paragraph: true,
|
|
align: "center",
|
|
style: {
|
|
paddingTop: "10px",
|
|
marginBottom: "10px",
|
|
color: colors.text,
|
|
fontSize: 16,
|
|
verticalAlign: "middle",
|
|
},
|
|
},
|
|
"For add a 2FA TOTP record you must have otpauth:// link or otpauth-migration:// link from Google Authenticator Migration QR-Code",
|
|
)
|
|
: null;
|
|
|
|
const createButton = TextInput({
|
|
placeholder: "otpauth(-migration)://",
|
|
label: "Add new TOTP record",
|
|
onChange: (changes) => {
|
|
try {
|
|
errorMessage = "";
|
|
let link = getTOTPByLink(changes);
|
|
if (link == null) {
|
|
throw new Error(
|
|
"Unsupported link type. Please use an otpauth:// or otpauth-migration:// link.",
|
|
);
|
|
}
|
|
|
|
if (Array.isArray(link)) {
|
|
storage.push(...link);
|
|
} else {
|
|
storage.push(link);
|
|
}
|
|
updateStorage(storage);
|
|
} catch (e) {
|
|
errorMessage = e.message;
|
|
updateStorage(storage);
|
|
}
|
|
},
|
|
labelStyle: {
|
|
backgroundColor: colors.notify,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
margin: "10px",
|
|
fontSize: "20px",
|
|
color: colors.text,
|
|
borderRadius: "5px",
|
|
width: "100%",
|
|
height: "45px",
|
|
},
|
|
});
|
|
|
|
const errorText = errorMessage
|
|
? Text(
|
|
{
|
|
style: {
|
|
color: colors.alert,
|
|
textAlign: "center",
|
|
margin: "5px",
|
|
},
|
|
},
|
|
errorMessage,
|
|
)
|
|
: null; //TODO: Check for work
|
|
|
|
const bottomContainer = View(
|
|
{
|
|
style: {
|
|
padding: "5px 0px",
|
|
backgroundColor: colors.bg,
|
|
},
|
|
},
|
|
[errorText, createButton].filter(Boolean),
|
|
);
|
|
|
|
const pageContainer = View(
|
|
{
|
|
style: {
|
|
backgroundColor: colors.bg,
|
|
height: "100vh",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between",
|
|
},
|
|
},
|
|
[
|
|
View(
|
|
{
|
|
style: {
|
|
textAlign: "center",
|
|
},
|
|
},
|
|
[
|
|
storage.length < 1
|
|
? addTOTPsHint
|
|
: Text(
|
|
{
|
|
align: "center",
|
|
paragraph: true,
|
|
style: {
|
|
marginBottom: "10px",
|
|
color: colors.bigText,
|
|
fontSize: 23,
|
|
fontWeight: "500",
|
|
verticalAlign: "middle",
|
|
},
|
|
},
|
|
"TOTP records:",
|
|
),
|
|
],
|
|
),
|
|
|
|
View(
|
|
{
|
|
style: {
|
|
flexGrow: 1,
|
|
overflow: "scroll",
|
|
},
|
|
},
|
|
[
|
|
...totpEntrys,
|
|
View(
|
|
{
|
|
style: {
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
marginTop: "20px",
|
|
marginBottom: "20px",
|
|
},
|
|
},
|
|
Link(
|
|
{
|
|
source: "https://github.com/Lisoveliy/totpfit/blob/main/docs/guides/how-to-add-totps/README.md",
|
|
},
|
|
"Instruction | Report issue (GitHub)",
|
|
),
|
|
),
|
|
],
|
|
),
|
|
|
|
bottomContainer,
|
|
],
|
|
);
|
|
|
|
return pageContainer;
|
|
},
|
|
});
|