feat: clear protection session
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { WebDirective } from './../../types';
|
import { WebDirective } from './../../types';
|
||||||
import { isDesktopApplication, preventRefreshing } from '@/utils';
|
import { isDesktopApplication, isSameDay, preventRefreshing } from '@/utils';
|
||||||
import template from '%/directives/account-menu.pug';
|
import template from '%/directives/account-menu.pug';
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import {
|
import {
|
||||||
@@ -18,17 +18,22 @@ import {
|
|||||||
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE,
|
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE,
|
||||||
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL,
|
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL,
|
||||||
STRING_UNSUPPORTED_BACKUP_FILE_VERSION,
|
STRING_UNSUPPORTED_BACKUP_FILE_VERSION,
|
||||||
Strings
|
Strings,
|
||||||
} from '@/strings';
|
} from '@/strings';
|
||||||
import { PasswordWizardType } from '@/types';
|
import { PasswordWizardType } from '@/types';
|
||||||
import { BackupFile, ContentType, Platform } from '@standardnotes/snjs';
|
import {
|
||||||
|
ApplicationEvent,
|
||||||
|
BackupFile,
|
||||||
|
ContentType,
|
||||||
|
Platform,
|
||||||
|
} from '@standardnotes/snjs';
|
||||||
import { confirmDialog, alertDialog } from '@/services/alertService';
|
import { confirmDialog, alertDialog } from '@/services/alertService';
|
||||||
import { autorun, IReactionDisposer } from 'mobx';
|
import { autorun, IReactionDisposer } from 'mobx';
|
||||||
import { storage, StorageKey } from '@/services/localStorage';
|
import { storage, StorageKey } from '@/services/localStorage';
|
||||||
import {
|
import {
|
||||||
disableErrorReporting,
|
disableErrorReporting,
|
||||||
enableErrorReporting,
|
enableErrorReporting,
|
||||||
errorReportingId
|
errorReportingId,
|
||||||
} from '@/services/errorReporting';
|
} from '@/services/errorReporting';
|
||||||
|
|
||||||
const ELEMENT_NAME_AUTH_EMAIL = 'email';
|
const ELEMENT_NAME_AUTH_EMAIL = 'email';
|
||||||
@@ -52,7 +57,7 @@ type FormData = {
|
|||||||
passcode: string;
|
passcode: string;
|
||||||
confirmPasscode: string;
|
confirmPasscode: string;
|
||||||
changingPasscode: boolean;
|
changingPasscode: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
type AccountMenuState = {
|
type AccountMenuState = {
|
||||||
formData: Partial<FormData>;
|
formData: Partial<FormData>;
|
||||||
@@ -72,21 +77,19 @@ type AccountMenuState = {
|
|||||||
showSessions: boolean;
|
showSessions: boolean;
|
||||||
errorReportingId: string | null;
|
errorReportingId: string | null;
|
||||||
keyStorageInfo: string | null;
|
keyStorageInfo: string | null;
|
||||||
}
|
protectionsDisabledUntil: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
||||||
|
public appVersion: string;
|
||||||
public appVersion: string
|
|
||||||
/** @template */
|
/** @template */
|
||||||
private closeFunction?: () => void
|
private closeFunction?: () => void;
|
||||||
private removeBetaWarningListener?: IReactionDisposer
|
private removeBetaWarningListener?: IReactionDisposer;
|
||||||
private removeSyncObserver?: IReactionDisposer
|
private removeSyncObserver?: IReactionDisposer;
|
||||||
|
private removeProtectionLengthObserver?: () => void;
|
||||||
|
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(
|
constructor($timeout: ng.ITimeoutService, appVersion: string) {
|
||||||
$timeout: ng.ITimeoutService,
|
|
||||||
appVersion: string,
|
|
||||||
) {
|
|
||||||
super($timeout);
|
super($timeout);
|
||||||
this.appVersion = appVersion;
|
this.appVersion = appVersion;
|
||||||
}
|
}
|
||||||
@@ -95,7 +98,9 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
appVersion: 'v' + ((window as any).electronAppVersion || this.appVersion),
|
appVersion: 'v' + ((window as any).electronAppVersion || this.appVersion),
|
||||||
passcodeAutoLockOptions: this.application.getAutolockService().getAutoLockIntervalOptions(),
|
passcodeAutoLockOptions: this.application
|
||||||
|
.getAutolockService()
|
||||||
|
.getAutoLockIntervalOptions(),
|
||||||
user: this.application.getUser(),
|
user: this.application.getUser(),
|
||||||
formData: {
|
formData: {
|
||||||
mergeLocal: true,
|
mergeLocal: true,
|
||||||
@@ -103,12 +108,14 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
},
|
},
|
||||||
mutable: {},
|
mutable: {},
|
||||||
showBetaWarning: false,
|
showBetaWarning: false,
|
||||||
errorReportingEnabled: storage.get(StorageKey.DisableErrorReporting) === false,
|
errorReportingEnabled:
|
||||||
|
storage.get(StorageKey.DisableErrorReporting) === false,
|
||||||
showSessions: false,
|
showSessions: false,
|
||||||
errorReportingId: errorReportingId(),
|
errorReportingId: errorReportingId(),
|
||||||
keyStorageInfo: Strings.keyStorageInfo(this.application),
|
keyStorageInfo: Strings.keyStorageInfo(this.application),
|
||||||
importData: null,
|
importData: null,
|
||||||
syncInProgress: false,
|
syncInProgress: false,
|
||||||
|
protectionsDisabledUntil: this.getProtectionsDisabledUntil(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,14 +141,16 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
user: this.application.getUser(),
|
user: this.application.getUser(),
|
||||||
canAddPasscode: !this.application.isEphemeralSession(),
|
canAddPasscode: !this.application.isEphemeralSession(),
|
||||||
hasPasscode: this.application.hasPasscode(),
|
hasPasscode: this.application.hasPasscode(),
|
||||||
showPasscodeForm: false
|
showPasscodeForm: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async $onInit() {
|
async $onInit() {
|
||||||
super.$onInit();
|
super.$onInit();
|
||||||
this.setState({
|
this.setState({
|
||||||
showSessions: this.appState.enableUnfinishedFeatures && await this.application.userCanManageSessions()
|
showSessions:
|
||||||
|
this.appState.enableUnfinishedFeatures &&
|
||||||
|
(await this.application.userCanManageSessions()),
|
||||||
});
|
});
|
||||||
|
|
||||||
const sync = this.appState.sync;
|
const sync = this.appState.sync;
|
||||||
@@ -153,14 +162,24 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
});
|
});
|
||||||
this.removeBetaWarningListener = autorun(() => {
|
this.removeBetaWarningListener = autorun(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showBetaWarning: this.appState.showBetaWarning
|
showBetaWarning: this.appState.showBetaWarning,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.removeProtectionLengthObserver = this.application.addEventObserver(
|
||||||
|
async () => {
|
||||||
|
this.setState({
|
||||||
|
protectionsDisabledUntil: this.getProtectionsDisabledUntil(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ApplicationEvent.ProtectionSessionExpiryDateChanged
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit() {
|
deinit() {
|
||||||
this.removeSyncObserver?.();
|
this.removeSyncObserver?.();
|
||||||
this.removeBetaWarningListener?.();
|
this.removeBetaWarningListener?.();
|
||||||
|
this.removeProtectionLengthObserver?.();
|
||||||
super.deinit();
|
super.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,17 +189,46 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getProtectionsDisabledUntil(): string | null {
|
||||||
|
const protectionExpiry = this.application.getProtectionSessionExpiryDate();
|
||||||
|
const now = new Date();
|
||||||
|
if (protectionExpiry > now) {
|
||||||
|
let f: Intl.DateTimeFormat;
|
||||||
|
if (isSameDay(protectionExpiry, now)) {
|
||||||
|
f = new Intl.DateTimeFormat(undefined, {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
f = new Intl.DateTimeFormat(undefined, {
|
||||||
|
weekday: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.format(protectionExpiry);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
async loadHost() {
|
async loadHost() {
|
||||||
const host = await this.application!.getHost();
|
const host = await this.application.getHost();
|
||||||
this.setState({
|
this.setState({
|
||||||
server: host,
|
server: host,
|
||||||
formData: {
|
formData: {
|
||||||
...this.getState().formData,
|
...this.getState().formData,
|
||||||
url: host
|
url: host,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableProtections() {
|
||||||
|
this.application.clearProtectionSession();
|
||||||
|
}
|
||||||
|
|
||||||
onHostInputChange() {
|
onHostInputChange() {
|
||||||
const url = this.getState().formData.url!;
|
const url = this.getState().formData.url!;
|
||||||
this.application!.setHost(url);
|
this.application!.setHost(url);
|
||||||
@@ -195,13 +243,13 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
encryptionStatusString: hasUser
|
encryptionStatusString: hasUser
|
||||||
? STRING_E2E_ENABLED
|
? STRING_E2E_ENABLED
|
||||||
: hasPasscode
|
: hasPasscode
|
||||||
? STRING_LOCAL_ENC_ENABLED
|
? STRING_LOCAL_ENC_ENABLED
|
||||||
: STRING_ENC_NOT_ENABLED,
|
: STRING_ENC_NOT_ENABLED,
|
||||||
encryptionEnabled,
|
encryptionEnabled,
|
||||||
mutable: {
|
mutable: {
|
||||||
...this.getState().mutable,
|
...this.getState().mutable,
|
||||||
backupEncrypted: encryptionEnabled
|
backupEncrypted: encryptionEnabled,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +261,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
const names = [
|
const names = [
|
||||||
ELEMENT_NAME_AUTH_EMAIL,
|
ELEMENT_NAME_AUTH_EMAIL,
|
||||||
ELEMENT_NAME_AUTH_PASSWORD,
|
ELEMENT_NAME_AUTH_PASSWORD,
|
||||||
ELEMENT_NAME_AUTH_PASSWORD_CONF
|
ELEMENT_NAME_AUTH_PASSWORD_CONF,
|
||||||
];
|
];
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
const element = document.getElementsByName(name)[0];
|
const element = document.getElementsByName(name)[0];
|
||||||
@@ -224,7 +272,10 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitAuthForm() {
|
submitAuthForm() {
|
||||||
if (!this.getState().formData.email || !this.getState().formData.user_password) {
|
if (
|
||||||
|
!this.getState().formData.email ||
|
||||||
|
!this.getState().formData.user_password
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.blurAuthFields();
|
this.blurAuthFields();
|
||||||
@@ -239,15 +290,15 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
return this.setState({
|
return this.setState({
|
||||||
formData: {
|
formData: {
|
||||||
...this.getState().formData,
|
...this.getState().formData,
|
||||||
...formData
|
...formData,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async login() {
|
async login() {
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
status: STRING_GENERATING_LOGIN_KEYS,
|
status: STRING_GENERATING_LOGIN_KEYS,
|
||||||
authenticating: true
|
authenticating: true,
|
||||||
});
|
});
|
||||||
const formData = this.getState().formData;
|
const formData = this.getState().formData;
|
||||||
const response = await this.application!.signIn(
|
const response = await this.application!.signIn(
|
||||||
@@ -261,7 +312,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
if (!error) {
|
if (!error) {
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
authenticating: false,
|
authenticating: false,
|
||||||
user_password: undefined
|
user_password: undefined,
|
||||||
});
|
});
|
||||||
this.close();
|
this.close();
|
||||||
return;
|
return;
|
||||||
@@ -269,28 +320,26 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
showLogin: true,
|
showLogin: true,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
user_password: undefined
|
user_password: undefined,
|
||||||
});
|
});
|
||||||
if (error.message) {
|
if (error.message) {
|
||||||
this.application!.alertService!.alert(error.message);
|
this.application!.alertService!.alert(error.message);
|
||||||
}
|
}
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
authenticating: false
|
authenticating: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async register() {
|
async register() {
|
||||||
const confirmation = this.getState().formData.password_conf;
|
const confirmation = this.getState().formData.password_conf;
|
||||||
if (confirmation !== this.getState().formData.user_password) {
|
if (confirmation !== this.getState().formData.user_password) {
|
||||||
this.application!.alertService!.alert(
|
this.application!.alertService!.alert(STRING_NON_MATCHING_PASSWORDS);
|
||||||
STRING_NON_MATCHING_PASSWORDS
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
confirmPassword: false,
|
confirmPassword: false,
|
||||||
status: STRING_GENERATING_REGISTER_KEYS,
|
status: STRING_GENERATING_REGISTER_KEYS,
|
||||||
authenticating: true
|
authenticating: true,
|
||||||
});
|
});
|
||||||
const response = await this.application!.register(
|
const response = await this.application!.register(
|
||||||
this.getState().formData.email!,
|
this.getState().formData.email!,
|
||||||
@@ -301,14 +350,12 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
const error = response.error;
|
const error = response.error;
|
||||||
if (error) {
|
if (error) {
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
status: undefined
|
status: undefined,
|
||||||
});
|
});
|
||||||
await this.setFormDataState({
|
await this.setFormDataState({
|
||||||
authenticating: false
|
authenticating: false,
|
||||||
});
|
});
|
||||||
this.application!.alertService!.alert(
|
this.application!.alertService!.alert(error.message);
|
||||||
error.message
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
await this.setFormDataState({ authenticating: false });
|
await this.setFormDataState({ authenticating: false });
|
||||||
this.close();
|
this.close();
|
||||||
@@ -320,8 +367,8 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
this.setFormDataState({
|
this.setFormDataState({
|
||||||
mergeLocal: !(await confirmDialog({
|
mergeLocal: !(await confirmDialog({
|
||||||
text: STRING_ACCOUNT_MENU_UNCHECK_MERGE,
|
text: STRING_ACCOUNT_MENU_UNCHECK_MERGE,
|
||||||
confirmButtonStyle: 'danger'
|
confirmButtonStyle: 'danger',
|
||||||
}))
|
})),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,17 +384,19 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async destroyLocalData() {
|
async destroyLocalData() {
|
||||||
if (await confirmDialog({
|
if (
|
||||||
text: STRING_SIGN_OUT_CONFIRMATION,
|
await confirmDialog({
|
||||||
confirmButtonStyle: "danger"
|
text: STRING_SIGN_OUT_CONFIRMATION,
|
||||||
})) {
|
confirmButtonStyle: 'danger',
|
||||||
|
})
|
||||||
|
) {
|
||||||
this.application.signOut();
|
this.application.signOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showRegister() {
|
showRegister() {
|
||||||
this.setFormDataState({
|
this.setFormDataState({
|
||||||
showRegister: true
|
showRegister: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,9 +408,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
const data = JSON.parse(e.target!.result as string);
|
const data = JSON.parse(e.target!.result as string);
|
||||||
resolve(data);
|
resolve(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.application!.alertService!.alert(
|
this.application!.alertService!.alert(STRING_INVALID_IMPORT_FILE);
|
||||||
STRING_INVALID_IMPORT_FILE
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
@@ -378,7 +425,8 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data.version || data.auth_params || data.keyParams) {
|
if (data.version || data.auth_params || data.keyParams) {
|
||||||
const version = data.version || data.keyParams?.version || data.auth_params?.version;
|
const version =
|
||||||
|
data.version || data.keyParams?.version || data.auth_params?.version;
|
||||||
if (
|
if (
|
||||||
this.application.protocolService.supportedVersions().includes(version)
|
this.application.protocolService.supportedVersions().includes(version)
|
||||||
) {
|
) {
|
||||||
@@ -396,52 +444,50 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
await this.setState({
|
await this.setState({
|
||||||
importData: {
|
importData: {
|
||||||
...this.getState().importData,
|
...this.getState().importData,
|
||||||
loading: true
|
loading: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const result = await this.application.importData(data);
|
const result = await this.application.importData(data);
|
||||||
this.setState({
|
this.setState({
|
||||||
importData: null
|
importData: null,
|
||||||
});
|
});
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
} else if ('error' in result) {
|
} else if ('error' in result) {
|
||||||
void alertDialog({
|
void alertDialog({
|
||||||
text: result.error
|
text: result.error,
|
||||||
});
|
});
|
||||||
} else if (result.errorCount) {
|
} else if (result.errorCount) {
|
||||||
void alertDialog({
|
void alertDialog({
|
||||||
text: StringImportError(result.errorCount)
|
text: StringImportError(result.errorCount),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
void alertDialog({
|
void alertDialog({
|
||||||
text: STRING_IMPORT_SUCCESS
|
text: STRING_IMPORT_SUCCESS,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async downloadDataArchive() {
|
async downloadDataArchive() {
|
||||||
this.application.getArchiveService().downloadBackup(this.getState().mutable.backupEncrypted);
|
this.application
|
||||||
|
.getArchiveService()
|
||||||
|
.downloadBackup(this.getState().mutable.backupEncrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
notesAndTagsCount() {
|
notesAndTagsCount() {
|
||||||
return this.application.getItems(
|
return this.application.getItems([ContentType.Note, ContentType.Tag])
|
||||||
[
|
.length;
|
||||||
ContentType.Note,
|
|
||||||
ContentType.Tag
|
|
||||||
]
|
|
||||||
).length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionStatusForNotes() {
|
encryptionStatusForNotes() {
|
||||||
const length = this.notesAndTagsCount();
|
const length = this.notesAndTagsCount();
|
||||||
return length + "/" + length + " notes and tags encrypted";
|
return length + '/' + length + ' notes and tags encrypted';
|
||||||
}
|
}
|
||||||
|
|
||||||
async reloadAutoLockInterval() {
|
async reloadAutoLockInterval() {
|
||||||
const interval = await this.application!.getAutolockService().getAutoLockInterval();
|
const interval = await this.application!.getAutolockService().getAutoLockInterval();
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedAutoLockInterval: interval
|
selectedAutoLockInterval: interval,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,7 +504,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
showLogin: false,
|
showLogin: false,
|
||||||
showRegister: false,
|
showRegister: false,
|
||||||
user_password: undefined,
|
user_password: undefined,
|
||||||
password_conf: undefined
|
password_conf: undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,30 +514,31 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
|
|
||||||
addPasscodeClicked() {
|
addPasscodeClicked() {
|
||||||
this.setFormDataState({
|
this.setFormDataState({
|
||||||
showPasscodeForm: true
|
showPasscodeForm: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitPasscodeForm() {
|
async submitPasscodeForm() {
|
||||||
const passcode = this.getState().formData.passcode!;
|
const passcode = this.getState().formData.passcode!;
|
||||||
if (passcode !== this.getState().formData.confirmPasscode!) {
|
if (passcode !== this.getState().formData.confirmPasscode!) {
|
||||||
this.application!.alertService!.alert(
|
this.application!.alertService!.alert(STRING_NON_MATCHING_PASSCODES);
|
||||||
STRING_NON_MATCHING_PASSCODES
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE, async () => {
|
await preventRefreshing(
|
||||||
if (this.application!.hasPasscode()) {
|
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE,
|
||||||
await this.application!.changePasscode(passcode);
|
async () => {
|
||||||
} else {
|
if (this.application!.hasPasscode()) {
|
||||||
await this.application!.setPasscode(passcode);
|
await this.application!.changePasscode(passcode);
|
||||||
|
} else {
|
||||||
|
await this.application!.setPasscode(passcode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
this.setFormDataState({
|
this.setFormDataState({
|
||||||
passcode: undefined,
|
passcode: undefined,
|
||||||
confirmPasscode: undefined,
|
confirmPasscode: undefined,
|
||||||
showPasscodeForm: false
|
showPasscodeForm: false,
|
||||||
});
|
});
|
||||||
this.refreshEncryptionStatus();
|
this.refreshEncryptionStatus();
|
||||||
}
|
}
|
||||||
@@ -502,13 +549,18 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async removePasscodePressed() {
|
async removePasscodePressed() {
|
||||||
await preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL, async () => {
|
await preventRefreshing(
|
||||||
if (await this.application!.removePasscode()) {
|
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL,
|
||||||
await this.application.getAutolockService().deleteAutolockPreference();
|
async () => {
|
||||||
await this.reloadAutoLockInterval();
|
if (await this.application!.removePasscode()) {
|
||||||
this.refreshEncryptionStatus();
|
await this.application
|
||||||
|
.getAutolockService()
|
||||||
|
.deleteAutolockPreference();
|
||||||
|
await this.reloadAutoLockInterval();
|
||||||
|
this.refreshEncryptionStatus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
openErrorReportingDialog() {
|
openErrorReportingDialog() {
|
||||||
@@ -526,7 +578,7 @@ class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
|||||||
anonymized. We use error reports to be alerted when something in our
|
anonymized. We use error reports to be alerted when something in our
|
||||||
code is causing unexpected errors and crashes in your application
|
code is causing unexpected errors and crashes in your application
|
||||||
experience.
|
experience.
|
||||||
`
|
`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,7 +608,7 @@ export class AccountMenu extends WebDirective {
|
|||||||
this.bindToController = true;
|
this.bindToController = true;
|
||||||
this.scope = {
|
this.scope = {
|
||||||
closeFunction: '&',
|
closeFunction: '&',
|
||||||
application: '='
|
application: '=',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Platform, platformFromString } from "@standardnotes/snjs";
|
import { Platform, platformFromString } from '@standardnotes/snjs';
|
||||||
|
|
||||||
declare const process : {
|
declare const process: {
|
||||||
env: {
|
env: {
|
||||||
NODE_ENV: string | null | undefined
|
NODE_ENV: string | null | undefined;
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isDev = process.env.NODE_ENV === 'development';
|
export const isDev = process.env.NODE_ENV === 'development';
|
||||||
@@ -36,11 +36,10 @@ let sharedDateFormatter: Intl.DateTimeFormat;
|
|||||||
export function dateToLocalizedString(date: Date) {
|
export function dateToLocalizedString(date: Date) {
|
||||||
if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
|
if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
|
||||||
if (!sharedDateFormatter) {
|
if (!sharedDateFormatter) {
|
||||||
const locale = (
|
const locale =
|
||||||
(navigator.languages && navigator.languages.length)
|
navigator.languages && navigator.languages.length
|
||||||
? navigator.languages[0]
|
? navigator.languages[0]
|
||||||
: navigator.language
|
: navigator.language;
|
||||||
);
|
|
||||||
sharedDateFormatter = new Intl.DateTimeFormat(locale, {
|
sharedDateFormatter = new Intl.DateTimeFormat(locale, {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'numeric',
|
month: 'numeric',
|
||||||
@@ -58,8 +57,21 @@ export function dateToLocalizedString(date: Date) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isSameDay(dateA: Date, dateB: Date): boolean {
|
||||||
|
return (
|
||||||
|
dateA.getFullYear() === dateB.getFullYear() &&
|
||||||
|
dateA.getMonth() === dateB.getMonth() &&
|
||||||
|
dateA.getDate() === dateB.getDate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/** Via https://davidwalsh.name/javascript-debounce-function */
|
/** Via https://davidwalsh.name/javascript-debounce-function */
|
||||||
export function debounce(this: any, func: any, wait: number, immediate = false) {
|
export function debounce(
|
||||||
|
this: any,
|
||||||
|
func: any,
|
||||||
|
wait: number,
|
||||||
|
immediate = false
|
||||||
|
) {
|
||||||
let timeout: any;
|
let timeout: any;
|
||||||
return () => {
|
return () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||||
@@ -131,7 +143,7 @@ if (!Array.prototype.includes) {
|
|||||||
|
|
||||||
// 8. Return false
|
// 8. Return false
|
||||||
return false;
|
return false;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +165,9 @@ declare const __WEB__: boolean;
|
|||||||
declare const __DESKTOP__: boolean;
|
declare const __DESKTOP__: boolean;
|
||||||
|
|
||||||
if (!__WEB__ && !__DESKTOP__) {
|
if (!__WEB__ && !__DESKTOP__) {
|
||||||
throw Error('Neither __WEB__ nor __DESKTOP__ is true. Check your configuration files.');
|
throw Error(
|
||||||
|
'Neither __WEB__ nor __DESKTOP__ is true. Check your configuration files.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDesktopApplication() {
|
export function isDesktopApplication() {
|
||||||
|
|||||||
@@ -164,6 +164,19 @@
|
|||||||
| {{self.encryptionStatusForNotes()}}
|
| {{self.encryptionStatusForNotes()}}
|
||||||
p.sk-p
|
p.sk-p
|
||||||
| {{self.state.encryptionStatusString}}
|
| {{self.state.encryptionStatusString}}
|
||||||
|
.sk-panel-section
|
||||||
|
.sk-panel-section-title Protections
|
||||||
|
.sk-panel-section-subtitle.info(ng-if="self.state.protectionsDisabledUntil")
|
||||||
|
| Protections are disabled until {{self.state.protectionsDisabledUntil}}
|
||||||
|
.sk-panel-section-subtitle.info(ng-if="!self.state.protectionsDisabledUntil")
|
||||||
|
| Protections are enabled
|
||||||
|
p.sk-p
|
||||||
|
| Actions like viewing protected notes, exporting decrypted backups,
|
||||||
|
| or revoking an active session, require additional authentication
|
||||||
|
| like entering your account password or application passcode.
|
||||||
|
.sk-panel-row(ng-if="self.state.protectionsDisabledUntil")
|
||||||
|
button.sk-button.info(ng-click="self.enableProtections()")
|
||||||
|
span.sk-label Enable protections
|
||||||
.sk-panel-section
|
.sk-panel-section
|
||||||
.sk-panel-section-title Passcode Lock
|
.sk-panel-section-title Passcode Lock
|
||||||
div(ng-if='!self.state.hasPasscode')
|
div(ng-if='!self.state.hasPasscode')
|
||||||
@@ -206,8 +219,7 @@
|
|||||||
ng-click='self.state.formData.showPasscodeForm = false'
|
ng-click='self.state.formData.showPasscodeForm = false'
|
||||||
) Cancel
|
) Cancel
|
||||||
div(ng-if='self.state.hasPasscode && !self.state.formData.showPasscodeForm')
|
div(ng-if='self.state.hasPasscode && !self.state.formData.showPasscodeForm')
|
||||||
.sk-p
|
.sk-panel-section-subtitle.info Passcode lock is enabled
|
||||||
| Passcode lock is enabled.
|
|
||||||
.sk-notification.contrast
|
.sk-notification.contrast
|
||||||
.sk-notification-title Options
|
.sk-notification-title Options
|
||||||
.sk-notification-text
|
.sk-notification-text
|
||||||
@@ -273,7 +285,7 @@
|
|||||||
.sk-panel-section
|
.sk-panel-section
|
||||||
.sk-panel-section-title Error Reporting
|
.sk-panel-section-title Error Reporting
|
||||||
.sk-panel-section-subtitle.info
|
.sk-panel-section-subtitle.info
|
||||||
| Automatic error reporting is {{ self.state.errorReportingEnabled ? 'enabled.' : 'disabled.' }}
|
| Automatic error reporting is {{ self.state.errorReportingEnabled ? 'enabled' : 'disabled' }}
|
||||||
p.sk-p
|
p.sk-p
|
||||||
| Help us improve Standard Notes by automatically submitting
|
| Help us improve Standard Notes by automatically submitting
|
||||||
| anonymized error reports.
|
| anonymized error reports.
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
"@reach/alert-dialog": "^0.13.0",
|
"@reach/alert-dialog": "^0.13.0",
|
||||||
"@reach/dialog": "^0.13.0",
|
"@reach/dialog": "^0.13.0",
|
||||||
"@standardnotes/sncrypto-web": "^1.2.10",
|
"@standardnotes/sncrypto-web": "^1.2.10",
|
||||||
"@standardnotes/snjs": "^2.0.53",
|
"@standardnotes/snjs": "^2.0.54",
|
||||||
"mobx": "^6.1.6",
|
"mobx": "^6.1.6",
|
||||||
"preact": "^10.5.12"
|
"preact": "^10.5.12"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1845,10 +1845,10 @@
|
|||||||
"@standardnotes/sncrypto-common" "^1.2.7"
|
"@standardnotes/sncrypto-common" "^1.2.7"
|
||||||
libsodium-wrappers "^0.7.8"
|
libsodium-wrappers "^0.7.8"
|
||||||
|
|
||||||
"@standardnotes/snjs@^2.0.53":
|
"@standardnotes/snjs@^2.0.54":
|
||||||
version "2.0.53"
|
version "2.0.54"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.53.tgz#ec89668fef57bf154dc0e145e4bc883cbe6be241"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.54.tgz#dab1dbf0405c2671aa73e4dbb944863bd434f629"
|
||||||
integrity sha512-9mlSitWXCBnQtMwhHMIV6/BaLIUXzWuQIMKkqWn43XYojnF33avEJteu0ciffZMAW9A2S7ORerRBVBbJxlqtdg==
|
integrity sha512-q1FErsVthiLpOarpKohoZhvXb8BGvgCBpXzbDZ64/15L2lErFUTYbXxyklBTy5DCbULwUh7wBvkm74JF10Ghlg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/sncrypto-common" "^1.2.9"
|
"@standardnotes/sncrypto-common" "^1.2.9"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user