diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 725d0aa7f..ff33ce7d6 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -390,6 +390,9 @@ "backup_file_info": { "message": "Backup your data to a file." }, + "password_policy_default_hint": { + "message": "Your password does not meet your organization's security requirements. Contact your administrator for more information." + }, "advisor": { "message": "Advisor" }, diff --git a/manifests/schema-chrome.json b/manifests/schema-chrome.json index b71a67a60..a18ba98c6 100644 --- a/manifests/schema-chrome.json +++ b/manifests/schema-chrome.json @@ -35,6 +35,16 @@ "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" + }, + "passwordPolicy": { + "title": "Password policy", + "description": "A regular expression to test if the password meets the security requirements. No slashes are needed (e.g. use [A-Z]+, but not use /[A-Z]+/).", + "type": "string" + }, + "passwordPolicyHint": { + "title": "Password policy hint", + "description": "Hint to show if the password doesn't meet the security requirements.", + "type": "string" } } } diff --git a/src/components/Popup/SetPasswordPage.vue b/src/components/Popup/SetPasswordPage.vue index 1b795d147..502d3fcd4 100644 --- a/src/components/Popup/SetPasswordPage.vue +++ b/src/components/Popup/SetPasswordPage.vue @@ -35,6 +35,20 @@ export default Vue.extend({ enforcePassword: function () { return this.$store.state.menu.enforcePassword; }, + passwordPolicy: function () { + try { + return new RegExp(this.$store.state.menu.passwordPolicy); + } catch { + console.warn( + "Invalid password policy. The password policy is not a valid regular expression.", + this.$store.state.menu.passwordPolicy + ); + return null; + } + }, + passwordPolicyHint: function () { + return this.$store.state.menu.passwordPolicyHint; + }, }, methods: { async removePassphrase() { @@ -49,6 +63,13 @@ export default Vue.extend({ return; } + if (this.passwordPolicy && !this.passwordPolicy.test(this.phrase)) { + const hint = + this.passwordPolicyHint || this.i18n.password_policy_default_hint; + this.$store.commit("notification/alert", hint); + return; + } + if (this.phrase !== this.confirm) { this.$store.commit("notification/alert", this.i18n.phrase_not_match); return; diff --git a/src/store/Menu.ts b/src/store/Menu.ts index 6cf83d52a..c73010255 100644 --- a/src/store/Menu.ts +++ b/src/store/Menu.ts @@ -18,6 +18,8 @@ export class Menu implements Module { enforceAutolock: await ManagedStorage.get("enforceAutolock"), storageArea: await ManagedStorage.get("storageArea"), feedbackURL: await ManagedStorage.get("feedbackURL"), + passwordPolicy: await ManagedStorage.get("passwordPolicy"), + passwordPolicyHint: await ManagedStorage.get("passwordPolicyHint"), }, mutations: { setZoom: (state: MenuState, zoom: number) => {