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
33 changes: 22 additions & 11 deletions schema-chrome.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
{
"type": "object",

"properties": {
"disableInstallHelp": {
"title": "Disable opening help page on install",
"description": "If set to true then help page will not be opened on install.",
"description": "If set to true, then help page will not be opened on install.",
"type": "boolean"
},

"disableBackup": {
"title": "Disable 3rd party backup",
"description": "If set to true then 3rd party backup options will be hidden. If 3rd party backup is already configured for a user this will not stop it.",
"type": "boolean"
"title": "Disable 3rd party backup",
"description": "If set to true, then 3rd party backup options will be hidden. If 3rd party backup is already configured for a user this will not stop it.",
"type": "boolean"
},
"disableExport": {
"title": "Disable import / export menu",
"description": "If set to true, then export buttons will be hidden.",
"type": "boolean"
},

"storageArea": {
"title": "Storage area",
"description": "Set to 'sync' or 'local'. If set will force user to use specified storage area. This setting will not check if a user is currently using another storage space and may hide data.",
"type": "string"
"title": "Storage area",
"description": "Set to 'sync' or 'local'. If set will force user to use specified storage area. This setting will not check if a user is currently using another storage space and may hide data.",
"type": "string"
},

"feedbackURL": {
"title": "Feedback URL",
"description": "Change the URL the feedback button opens.",
"type": "string"
},
"enforcePassword": {
"title": "Enforce password",
"description": "If set to true, then user will be prompted to set a password before adding an account (if none set) and the remove password button will be hidden.",
"type": "boolean"
},
"enforceAutolock": {
"title": "Enforce autolock",
"description": "If any value is set, then the user will not be able to change the autolock setting. Set to a number in minutes.",
"type": "number"
}
}
}
35 changes: 23 additions & 12 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
message.info.windowWidth
);
} else if (message.action === "cachePassphrase") {
document.cookie = `passphrase="${message.value}${getCookieExpiry()}"`;
cachedPassphrase = message.value;
clearTimeout(autolockTimeout);
setAutolock();
Expand Down Expand Up @@ -405,25 +404,37 @@ chrome.commands.onCommand.addListener(async (command: string) => {
}
});

function setAutolock() {
async function setAutolock() {
const enforcedAutolock = Number(await ManagedStorage.get("enforceAutolock"));

if (enforcedAutolock) {
if (enforcedAutolock > 0) {
document.cookie = `passphrase="${getCachedPassphrase()}${getCookieExpiry(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't we discarded cookies in the recent design?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's only part of #395 currently. There are some changes to how we do cookies that the PR doesn't have yet, so I'm going to go through and remove them again after merge.

enforcedAutolock
)}"`;
autolockTimeout = setTimeout(() => {
cachedPassphrase = "";
}, enforcedAutolock * 60000);
return;
}
}

if (Number(localStorage.autolock) > 0) {
document.cookie = `passphrase="${getCachedPassphrase()}${getCookieExpiry()}"`;
document.cookie = `passphrase="${getCachedPassphrase()}${getCookieExpiry(
Number(localStorage.autolock)
)}"`;
autolockTimeout = setTimeout(() => {
cachedPassphrase = "";
}, Number(localStorage.autolock) * 60000);
}
}

function getCookieExpiry() {
if (localStorage.autolock && Number(localStorage.autolock) > 0) {
const offset = Number(localStorage.autolock) * 60000;
const now = new Date().getTime();
const autolockExpiry = new Date(now + offset).toUTCString();
function getCookieExpiry(time: number) {
const offset = time * 60000;
const now = new Date().getTime();
const autolockExpiry = new Date(now + offset).toUTCString();

return `;expires=${autolockExpiry}`;
} else {
return "";
}
return `;expires=${autolockExpiry}`;
}

function getCachedPassphrase() {
Expand Down
63 changes: 34 additions & 29 deletions src/components/Popup/ExportPage.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
<template>
<div>
<div class="text warning" v-if="!encryption.getEncryptionStatus()">
{{ i18n.export_info }}
<div v-show="!exportDisabled">
<div class="text warning" v-if="!encryption.getEncryptionStatus()">
{{ i18n.export_info }}
</div>
<div class="text warning" v-if="unsupportedAccounts">
{{ i18n.otp_unsupported_warn }}
</div>
<a
download="authenticator.txt"
v-bind:href="exportOneLineOtpAuthFile"
v-if="!unsupportedAccounts"
class="button"
target="_blank"
>{{ i18n.download_backup }}</a
>
<a
download="authenticator.json"
v-bind:href="exportFile"
class="button"
target="_blank"
v-else
>{{ i18n.download_backup }}</a
>
<a
download="authenticator.json"
v-bind:href="exportEncryptedFile"
v-if="encryption.getEncryptionStatus()"
class="button"
target="_blank"
>{{ i18n.download_enc_backup }}</a
>
</div>
<div class="text warning" v-if="unsupportedAccounts">
{{ i18n.otp_unsupported_warn }}
</div>
<a
download="authenticator.txt"
v-bind:href="exportOneLineOtpAuthFile"
v-if="!unsupportedAccounts"
class="button"
target="_blank"
>{{ i18n.download_backup }}</a
>
<a
download="authenticator.json"
v-bind:href="exportFile"
class="button"
target="_blank"
v-else
>{{ i18n.download_backup }}</a
>
<a
download="authenticator.json"
v-bind:href="exportEncryptedFile"
v-if="encryption.getEncryptionStatus()"
class="button"
target="_blank"
>{{ i18n.download_enc_backup }}</a
>
<a class="button" href="import.html" target="_blank">{{
i18n.import_backup
}}</a>
Expand Down Expand Up @@ -57,6 +59,9 @@ export default Vue.extend({
computed: {
encryption: function() {
return this.$store.state.accounts.encryption;
},
exportDisabled: function() {
return this.$store.state.menu.exportDisabled;
}
}
});
Expand Down
9 changes: 9 additions & 0 deletions src/components/Popup/MainBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ export default Vue.extend({
computed,
methods: {
showInfo(page: string) {
if (page === "AddMethodPage") {
if (
this.$store.state.menu.enforcePassword &&
!this.$store.state.accounts.encryption.getEncryptionStatus()
) {
page = "SetPasswordPage";
}
}

this.$store.commit("style/showInfo");
this.$store.commit("currentView/changeView", page);
},
Expand Down
8 changes: 8 additions & 0 deletions src/components/Popup/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ export default Vue.extend({
return;
},
async beginCapture() {
if (
this.$store.state.menu.enforcePassword &&
!this.$store.state.accounts.encryption.getEncryptionStatus()
) {
this.$store.commit("style/showInfo");
this.$store.commit("currentView/changeView", "SetPasswordPage");
return;
}
// Insert content script
await new Promise(
(resolve: () => void, reject: (reason: Error) => void) => {
Expand Down
10 changes: 9 additions & 1 deletion src/components/Popup/PrefrencesPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
min="0"
style="width: 70px;"
v-model="autolock"
:disabled="Boolean(enforceAutolock)"
/>
<span style="margin-top: 10px;">{{ i18n.minutes }}</span>
</div>
Expand Down Expand Up @@ -70,9 +71,16 @@ export default Vue.extend({
encryption(): IEncryption {
return this.$store.state.accounts.encryption;
},
enforceAutolock() {
return this.$store.state.menu.enforceAutolock;
},
autolock: {
get(): number {
return this.$store.state.menu.autolock;
if (this.$store.state.menu.enforceAutolock) {
return this.$store.state.menu.enforceAutolock;
} else {
return this.$store.state.menu.autolock;
}
},
set(autolock: number) {
this.$store.commit("menu/setAutolock", autolock);
Expand Down
27 changes: 24 additions & 3 deletions src/components/Popup/SetPasswordPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@
v-model="confirm"
v-on:keyup.enter="changePassphrase()"
/>
<div id="security-save" v-on:click="changePassphrase()">{{ i18n.ok }}</div>
<div id="security-remove" v-on:click="removePassphrase()">
{{ i18n.remove }}
<div v-show="!enforcePassword">
<div id="security-save" v-on:click="changePassphrase()">
{{ i18n.ok }}
</div>
<div id="security-remove" v-on:click="removePassphrase()">
{{ i18n.remove }}
</div>
</div>
<div
class="button-small"
v-show="enforcePassword"
v-on:click="changePassphrase()"
>
{{ i18n.ok }}
</div>
</div>
</template>
Expand All @@ -26,20 +37,30 @@ export default Vue.extend({
confirm: ""
};
},
computed: {
enforcePassword: function() {
return this.$store.state.menu.enforcePassword;
}
},
methods: {
async removePassphrase() {
await this.$store.dispatch("accounts/changePassphrase", "");
this.$store.commit("notification/alert", this.i18n.updateSuccess);
return;
},
async changePassphrase() {
if (this.phrase === "") {
return;
}

if (this.phrase !== this.confirm) {
this.$store.commit("notification/alert", this.i18n.phrase_not_match);
return;
}

await this.$store.dispatch("accounts/changePassphrase", this.phrase);
this.$store.commit("notification/alert", this.i18n.updateSuccess);
this.$store.commit("style/hideInfo");
return;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/store/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export class Menu implements IModule {
useHighContrast: localStorage.highContrast === "true",
autolock: Number(localStorage.autolock) || 0,
backupDisabled: await ManagedStorage.get("disableBackup"),
exportDisabled: await ManagedStorage.get("disableExport"),
enforcePassword: await ManagedStorage.get("enforcePassword"),
enforceAutolock: await ManagedStorage.get("enforceAutolock"),
storageArea: await ManagedStorage.get("storageArea"),
feedbackURL: await ManagedStorage.get("feedbackURL")
},
Expand Down