Skip to content

Commit

Permalink
Remove tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
Natarajan Krishnaswami committed Sep 11, 2023
1 parent 6c01783 commit 336bb2b
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 93 deletions.
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ <h1 data-l10n-id="title-settings">Settings</h1>
<a id="export" data-l10n-id="settings-export" data-role="button" data-theme="a">Export keys</a>
</p>
<p>
<a id="import" data-l10n-id="settings-import" data-role="button" data-theme="a">Import keys</a>
<input id="import-files" multiple type="file" style="display: none">
<a id="import" data-l10n-id="settings-import" data-role="button" data-theme="a">Import keys</a>
<input id="import-files" multiple type="file" style="display: none">
</p>
</div>
</section>
Expand Down
182 changes: 91 additions & 91 deletions js/gauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
$.mobile.navigate('#main');
} else {
$('#keySecret').focus();
}
}
});

$('#addKeyCancel').click(function() {
Expand All @@ -162,15 +162,15 @@

var clearAddFields = function() {
$('#keyAccount').val('');
$('#keySecret').val('');
$('#keySecret').val('');
};

$('#edit').click(function() { toggleEdit(); });
$('#export').click(function() { exportAccounts(); });
$('#import').click(function() {
// Sneakily "delegate" the click to an invisible INPUT
// element. That lets us use the input's `files`
// while maintaining a consistent button UI.
// Sneakily "delegate" the click to an invisible INPUT
// element. That lets us use the input's `files`
// while maintaining a consistent button UI.
$('#import-files').click();
});
$('#import-files').change(function(evt) {
Expand Down Expand Up @@ -198,14 +198,14 @@
});
accElem.append(delLink);
} else {
// If not selecting for deletion, copy the key on click.
accElem.click(function () {
navigator.clipboard.writeText(key).then(function () {
toastr.success(`Copied key ${key} for ${account.name}`)
}).catch(function (e) {
toastr.error('Unable to copy key: missing clipboard access permission');
});
});
// If not selecting for deletion, copy the key on click.
accElem.click(function () {
navigator.clipboard.writeText(key).then(function () {
toastr.success(`Copied key ${key} for ${account.name}`)
}).catch(function (e) {
toastr.error('Unable to copy key: missing clipboard access permission');
});
});
}

// Add HTML element
Expand All @@ -231,91 +231,91 @@
saveAs(blob, 'gauth-export.json');
};

// Helper to ensure that parsed objects are arrays of
// name/secret keyed objects.
const validateAccountData = function(data) {
if (!(data instanceof Array)) {
throw new SyntaxError("Account list is not an array");
}
if (data.length === 0) {
throw new SyntaxError("Account list is empty");
}
// Helper to check if its argument is a string.
const isNonemptyString = function (val) {
return (typeof val === "string" || val instanceof String) &&
val.length > 0;
}

for (let index = 0; index < data.length; ++index) {
const element = data[index];
const keys = Object.keys(element).sort();
if (keys.length !== 2) {
throw new SyntaxError(`Account data at index ${index} has unexpected entries: ${keys}`);
}
if (keys[0] !== "name") {
throw new SyntaxError(`Account data at index ${index} has no account name`);
} else if(!isNonemptyString(element.name)) {
throw new SyntaxError(`Account data at index ${index} has invalid account name: '${element.name}'`);
}
if (keys[1] !== "secret") {
throw new SyntaxError(`Account data at index ${index} has no account secret`);
} else if(!isNonemptyString(element.secret)) {
throw new SyntaxError(`Account data at index ${index} has invalid account secret: '${element.secret}'`);
}
}
};

// Merge new_data into dest, skipping duplicate secrets.
// This requires both to be valid account lists.
var mergeAccountData = function(dest, new_data) {
const existing = {};
for (const element of dest) {
existing[element.secret] = element.name;
}
for (const element of new_data) {
const prior_name = existing[element.secret];
if (prior_name !== undefined) {
toastr.warning(`Skipping account "${element.name}"; duplicate of "${prior_name}"`);
} else {
dest.push({name: element.name, secret: element.secret});
}
}
};
// Helper to ensure that parsed objects are arrays of
// name/secret keyed objects.
const validateAccountData = function(data) {
if (!(data instanceof Array)) {
throw new SyntaxError("Account list is not an array");
}
if (data.length === 0) {
throw new SyntaxError("Account list is empty");
}
// Helper to check if its argument is a string.
const isNonemptyString = function (val) {
return (typeof val === "string" || val instanceof String) &&
val.length > 0;
}

for (let index = 0; index < data.length; ++index) {
const element = data[index];
const keys = Object.keys(element).sort();
if (keys.length !== 2) {
throw new SyntaxError(`Account data at index ${index} has unexpected entries: ${keys}`);
}
if (keys[0] !== "name") {
throw new SyntaxError(`Account data at index ${index} has no account name`);
} else if(!isNonemptyString(element.name)) {
throw new SyntaxError(`Account data at index ${index} has invalid account name: '${element.name}'`);
}
if (keys[1] !== "secret") {
throw new SyntaxError(`Account data at index ${index} has no account secret`);
} else if(!isNonemptyString(element.secret)) {
throw new SyntaxError(`Account data at index ${index} has invalid account secret: '${element.secret}'`);
}
}
};

// Merge new_data into dest, skipping duplicate secrets.
// This requires both to be valid account lists.
var mergeAccountData = function(dest, new_data) {
const existing = {};
for (const element of dest) {
existing[element.secret] = element.name;
}
for (const element of new_data) {
const prior_name = existing[element.secret];
if (prior_name !== undefined) {
toastr.warning(`Skipping account "${element.name}"; duplicate of "${prior_name}"`);
} else {
dest.push({name: element.name, secret: element.secret});
}
}
};

var importAccounts = async function(evt) {
const files = evt.target.files;
if (files.length === 0) {
toastr.warning("Please select one or more files to upload.");
return;
}
const new_accounts = [];
var valid_files = 0;
for (const file of files) {
const text = await file.text();
try {
const data = JSON.parse(text)
validateAccountData(data);
valid_files += 1;
let len = new_accounts.length;
mergeAccountData(new_accounts, data);
console.log(`Read ${data.length} accounts from ${file.name}, ${new_accounts.length - len} unique`);
} catch (e) {
console.warn(`Error processing ${file.name}`, e);
toastr.error(e, `Import failed on ${file.name}: invalid JSON data.`);
}
}
if (new_accounts.length > 0) {
const accounts = storageService.getObject('accounts');
var len = accounts.length;
mergeAccountData(accounts, new_accounts);
len = accounts.length - len;
console.log(`Added total of new ${len} new accounts`);
storageService.setObject('accounts', accounts);
updateKeys();
toastr.success(`Imported ${new_accounts.length} accounts (${len} new) from ${valid_files} file${valid_files > 1 ? "s" : ""}`);
} else {
toastr.warning('No accounts imported');
}
const new_accounts = [];
var valid_files = 0;
for (const file of files) {
const text = await file.text();
try {
const data = JSON.parse(text)
validateAccountData(data);
valid_files += 1;
let len = new_accounts.length;
mergeAccountData(new_accounts, data);
console.log(`Read ${data.length} accounts from ${file.name}, ${new_accounts.length - len} unique`);
} catch (e) {
console.warn(`Error processing ${file.name}`, e);
toastr.error(e, `Import failed on ${file.name}: invalid JSON data.`);
}
}
if (new_accounts.length > 0) {
const accounts = storageService.getObject('accounts');
var len = accounts.length;
mergeAccountData(accounts, new_accounts);
len = accounts.length - len;
console.log(`Added total of new ${len} new accounts`);
storageService.setObject('accounts', accounts);
updateKeys();
toastr.success(`Imported ${new_accounts.length} accounts (${len} new) from ${valid_files} file${valid_files > 1 ? "s" : ""}`);
} else {
toastr.warning('No accounts imported');
}
};

var deleteAccount = function(index) {
Expand Down

0 comments on commit 336bb2b

Please sign in to comment.