refactor: update SNJS + eslint
This commit is contained in:
11
.eslintrc
11
.eslintrc
@@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
"extends": ["eslint:recommended", "semistandard", "prettier"],
|
"extends": ["eslint:recommended", "prettier"],
|
||||||
"parser": "babel-eslint",
|
"parser": "@typescript-eslint/parser",
|
||||||
"rules": {
|
"rules": {
|
||||||
"standard/no-callback-literal": 0, // Disable this as we have too many callbacks relying on literals
|
"standard/no-callback-literal": "off", // Disable this as we have too many callbacks relying on literals
|
||||||
"no-throw-literal": 0,
|
"no-throw-literal": "off",
|
||||||
// "no-console": "error",
|
"camelcase": "off"
|
||||||
"semi": 1
|
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true
|
"browser": true
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { WebDirective } from './../../types';
|
import { WebDirective } from './../../types';
|
||||||
import { isDesktopApplication, preventRefreshing } from '@/utils';
|
import { isDesktopApplication, preventRefreshing } from '@/utils';
|
||||||
import template from '%/directives/account-menu.pug';
|
import template from '%/directives/account-menu.pug';
|
||||||
import { ProtectedAction, ContentType } from '@standardnotes/snjs';
|
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import {
|
import {
|
||||||
STRING_ACCOUNT_MENU_UNCHECK_MERGE,
|
STRING_ACCOUNT_MENU_UNCHECK_MERGE,
|
||||||
@@ -10,8 +9,6 @@ import {
|
|||||||
STRING_LOCAL_ENC_ENABLED,
|
STRING_LOCAL_ENC_ENABLED,
|
||||||
STRING_ENC_NOT_ENABLED,
|
STRING_ENC_NOT_ENABLED,
|
||||||
STRING_IMPORT_SUCCESS,
|
STRING_IMPORT_SUCCESS,
|
||||||
STRING_REMOVE_PASSCODE_CONFIRMATION,
|
|
||||||
STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM,
|
|
||||||
STRING_NON_MATCHING_PASSCODES,
|
STRING_NON_MATCHING_PASSCODES,
|
||||||
STRING_NON_MATCHING_PASSWORDS,
|
STRING_NON_MATCHING_PASSWORDS,
|
||||||
STRING_INVALID_IMPORT_FILE,
|
STRING_INVALID_IMPORT_FILE,
|
||||||
@@ -23,7 +20,7 @@ import {
|
|||||||
STRING_UNSUPPORTED_BACKUP_FILE_VERSION
|
STRING_UNSUPPORTED_BACKUP_FILE_VERSION
|
||||||
} from '@/strings';
|
} from '@/strings';
|
||||||
import { PasswordWizardType } from '@/types';
|
import { PasswordWizardType } from '@/types';
|
||||||
import { BackupFile } from '@standardnotes/snjs';
|
import { BackupFile, ContentType } 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';
|
||||||
@@ -35,22 +32,22 @@ const ELEMENT_NAME_AUTH_PASSWORD = 'password';
|
|||||||
const ELEMENT_NAME_AUTH_PASSWORD_CONF = 'password_conf';
|
const ELEMENT_NAME_AUTH_PASSWORD_CONF = 'password_conf';
|
||||||
|
|
||||||
type FormData = {
|
type FormData = {
|
||||||
email: string
|
email: string;
|
||||||
user_password: string
|
user_password: string;
|
||||||
password_conf: string
|
password_conf: string;
|
||||||
confirmPassword: boolean
|
confirmPassword: boolean;
|
||||||
showLogin: boolean
|
showLogin: boolean;
|
||||||
showRegister: boolean
|
showRegister: boolean;
|
||||||
showPasscodeForm: boolean
|
showPasscodeForm: boolean;
|
||||||
strictSignin?: boolean
|
strictSignin?: boolean;
|
||||||
ephemeral: boolean
|
ephemeral: boolean;
|
||||||
mergeLocal?: boolean
|
mergeLocal?: boolean;
|
||||||
url: string
|
url: string;
|
||||||
authenticating: boolean
|
authenticating: boolean;
|
||||||
status: string
|
status: string;
|
||||||
passcode: string
|
passcode: string;
|
||||||
confirmPasscode: string
|
confirmPasscode: string;
|
||||||
changingPasscode: boolean
|
changingPasscode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountMenuState = {
|
type AccountMenuState = {
|
||||||
@@ -72,7 +69,7 @@ type AccountMenuState = {
|
|||||||
showSessions: boolean;
|
showSessions: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> {
|
class AccountMenuCtrl extends PureViewCtrl<unknown, AccountMenuState> {
|
||||||
|
|
||||||
public appVersion: string
|
public appVersion: string
|
||||||
/** @template */
|
/** @template */
|
||||||
@@ -331,26 +328,6 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> {
|
|||||||
this.appState.openSessionsModal();
|
this.appState.openSessionsModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
async openPrivilegesModal() {
|
|
||||||
const run = () => {
|
|
||||||
this.application!.presentPrivilegesManagementModal();
|
|
||||||
this.close();
|
|
||||||
};
|
|
||||||
const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManagePrivileges
|
|
||||||
);
|
|
||||||
if (needsPrivilege) {
|
|
||||||
this.application!.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManagePrivileges,
|
|
||||||
() => {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async destroyLocalData() {
|
async destroyLocalData() {
|
||||||
if (await confirmDialog({
|
if (await confirmDialog({
|
||||||
text: STRING_SIGN_OUT_CONFIRMATION,
|
text: STRING_SIGN_OUT_CONFIRMATION,
|
||||||
@@ -394,56 +371,46 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> {
|
|||||||
* @template
|
* @template
|
||||||
*/
|
*/
|
||||||
async importFileSelected(files: File[]) {
|
async importFileSelected(files: File[]) {
|
||||||
const run = async () => {
|
const file = files[0];
|
||||||
const file = files[0];
|
const data = await this.readFile(file);
|
||||||
const data = await this.readFile(file);
|
if (!data) {
|
||||||
if (!data) {
|
return;
|
||||||
|
}
|
||||||
|
if (data.version || data.auth_params || data.keyParams) {
|
||||||
|
const version = data.version || data.keyParams?.version || data.auth_params?.version;
|
||||||
|
if (
|
||||||
|
!this.application!.protocolService!.supportedVersions().includes(version)
|
||||||
|
) {
|
||||||
|
await this.setState({ importData: null });
|
||||||
|
alertDialog({ text: STRING_UNSUPPORTED_BACKUP_FILE_VERSION });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data.version || data.auth_params || data.keyParams) {
|
if (data.keyParams || data.auth_params) {
|
||||||
const version = data.version || data.keyParams?.version || data.auth_params?.version;
|
await this.setState({
|
||||||
if (
|
importData: {
|
||||||
!this.application!.protocolService!.supportedVersions().includes(version)
|
...this.getState().importData,
|
||||||
) {
|
requestPassword: true,
|
||||||
await this.setState({ importData: null });
|
data,
|
||||||
alertDialog({ text: STRING_UNSUPPORTED_BACKUP_FILE_VERSION });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data.keyParams || data.auth_params) {
|
|
||||||
await this.setState({
|
|
||||||
importData: {
|
|
||||||
...this.getState().importData,
|
|
||||||
requestPassword: true,
|
|
||||||
data,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const element = document.getElementById(
|
|
||||||
ELEMENT_ID_IMPORT_PASSWORD_INPUT
|
|
||||||
);
|
|
||||||
if (element) {
|
|
||||||
element.scrollIntoView(false);
|
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
await this.performImport(data, undefined);
|
const element = document.getElementById(
|
||||||
|
ELEMENT_ID_IMPORT_PASSWORD_INPUT
|
||||||
|
);
|
||||||
|
if (element) {
|
||||||
|
element.scrollIntoView(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await this.performImport(data, undefined);
|
await this.performImport(data, undefined);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManageBackups
|
|
||||||
);
|
|
||||||
if (needsPrivilege) {
|
|
||||||
this.application!.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManageBackups,
|
|
||||||
run
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
run();
|
await this.performImport(data, undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async performImport(data: BackupFile, password?: string) {
|
async performImport(data: BackupFile, password?: string) {
|
||||||
|
if (!(await this.application.authorizeFileImport())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await this.setState({
|
await this.setState({
|
||||||
importData: {
|
importData: {
|
||||||
...this.getState().importData,
|
...this.getState().importData,
|
||||||
@@ -499,23 +466,11 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async selectAutoLockInterval(interval: number) {
|
async selectAutoLockInterval(interval: number) {
|
||||||
const run = async () => {
|
if (!(await this.application.authorizeAutolockIntervalChange())) {
|
||||||
await this.application!.getAutolockService().setAutoLockInterval(interval);
|
return;
|
||||||
this.reloadAutoLockInterval();
|
|
||||||
};
|
|
||||||
const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManagePasscode
|
|
||||||
);
|
|
||||||
if (needsPrivilege) {
|
|
||||||
this.application!.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManagePasscode,
|
|
||||||
() => {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
}
|
||||||
|
await this.application!.getAutolockService().setAutoLockInterval(interval);
|
||||||
|
this.reloadAutoLockInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
hidePasswordForm() {
|
hidePasswordForm() {
|
||||||
@@ -562,53 +517,18 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async changePasscodePressed() {
|
async changePasscodePressed() {
|
||||||
const run = () => {
|
this.getState().formData.changingPasscode = true;
|
||||||
this.getState().formData.changingPasscode = true;
|
this.addPasscodeClicked();
|
||||||
this.addPasscodeClicked();
|
|
||||||
};
|
|
||||||
const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManagePasscode
|
|
||||||
);
|
|
||||||
if (needsPrivilege) {
|
|
||||||
this.application!.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManagePasscode,
|
|
||||||
run
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async removePasscodePressed() {
|
async removePasscodePressed() {
|
||||||
const run = async () => {
|
await preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL, async () => {
|
||||||
const signedIn = this.application!.hasAccount();
|
if (await this.application!.removePasscode()) {
|
||||||
let message = STRING_REMOVE_PASSCODE_CONFIRMATION;
|
await this.application.getAutolockService().deleteAutolockPreference();
|
||||||
if (!signedIn) {
|
await this.reloadAutoLockInterval();
|
||||||
message += STRING_REMOVE_PASSCODE_OFFLINE_ADDENDUM;
|
|
||||||
}
|
|
||||||
if (await confirmDialog({
|
|
||||||
text: message,
|
|
||||||
confirmButtonStyle: 'danger'
|
|
||||||
})) {
|
|
||||||
await preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL, async () => {
|
|
||||||
await this.application.getAutolockService().deleteAutolockPreference();
|
|
||||||
await this.application!.removePasscode();
|
|
||||||
await this.reloadAutoLockInterval();
|
|
||||||
});
|
|
||||||
this.refreshEncryptionStatus();
|
this.refreshEncryptionStatus();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
const needsPrivilege = await this.application!.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManagePasscode
|
|
||||||
);
|
|
||||||
if (needsPrivilege) {
|
|
||||||
this.application!.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManagePasscode,
|
|
||||||
run
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openErrorReportingDialog() {
|
openErrorReportingDialog() {
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import { SNComponent, PurePayload, ComponentMutator, AppDataField, ContentType } from '@standardnotes/snjs';
|
import {
|
||||||
|
SNComponent,
|
||||||
|
PurePayload,
|
||||||
|
ComponentMutator,
|
||||||
|
AppDataField,
|
||||||
|
EncryptionIntent,
|
||||||
|
ApplicationService,
|
||||||
|
ApplicationEvent,
|
||||||
|
removeFromArray,
|
||||||
|
} from '@standardnotes/snjs';
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
// An interface used by the Desktop app to interact with SN
|
// An interface used by the Desktop app to interact with SN
|
||||||
import { isDesktopApplication } from '@/utils';
|
import { isDesktopApplication } from '@/utils';
|
||||||
import { EncryptionIntent, ApplicationService, ApplicationEvent, removeFromArray } from '@standardnotes/snjs';
|
|
||||||
import { Bridge } from './bridge';
|
import { Bridge } from './bridge';
|
||||||
|
|
||||||
type UpdateObserverCallback = (component: SNComponent) => void
|
type UpdateObserverCallback = (component: SNComponent) => void
|
||||||
@@ -20,7 +28,8 @@ export class DesktopManager extends ApplicationService {
|
|||||||
componentActivationObservers: ComponentActivationObserver[] = []
|
componentActivationObservers: ComponentActivationObserver[] = []
|
||||||
updateObservers: {
|
updateObservers: {
|
||||||
callback: UpdateObserverCallback
|
callback: UpdateObserverCallback
|
||||||
}[] = []
|
}[] = [];
|
||||||
|
|
||||||
isDesktop = isDesktopApplication();
|
isDesktop = isDesktopApplication();
|
||||||
|
|
||||||
dataLoaded = false
|
dataLoaded = false
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { isDesktopApplication, isDev } from '@/utils';
|
import { isDesktopApplication, isDev } from '@/utils';
|
||||||
import pull from 'lodash/pull';
|
import pull from 'lodash/pull';
|
||||||
import {
|
import {
|
||||||
ProtectedAction,
|
|
||||||
ApplicationEvent,
|
ApplicationEvent,
|
||||||
SNTag,
|
SNTag,
|
||||||
SNNote,
|
SNNote,
|
||||||
SNUserPrefs,
|
|
||||||
ContentType,
|
ContentType,
|
||||||
SNSmartTag,
|
|
||||||
PayloadSource,
|
PayloadSource,
|
||||||
DeinitSource,
|
DeinitSource,
|
||||||
UuidString,
|
UuidString,
|
||||||
@@ -231,8 +228,7 @@ export class AppState {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const approved = this.application.authorizeNoteAccess(note);
|
if (await this.application.authorizeNoteAccess(note)) {
|
||||||
if (approved === true || await approved) {
|
|
||||||
const activeEditor = this.getActiveEditor();
|
const activeEditor = this.getActiveEditor();
|
||||||
if (!activeEditor) {
|
if (!activeEditor) {
|
||||||
this.application.editorGroup.createEditor(noteUuid);
|
this.application.editorGroup.createEditor(noteUuid);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { PermissionDialog } from '@standardnotes/snjs';
|
|
||||||
import { ComponentModalScope } from './../directives/views/componentModal';
|
import { ComponentModalScope } from './../directives/views/componentModal';
|
||||||
import { AccountSwitcherScope, PermissionsModalScope } from './../types';
|
import { AccountSwitcherScope, PermissionsModalScope } from './../types';
|
||||||
import { ComponentGroup } from './component_group';
|
import { ComponentGroup } from './component_group';
|
||||||
@@ -9,7 +8,9 @@ import {
|
|||||||
SNApplication,
|
SNApplication,
|
||||||
platformFromString,
|
platformFromString,
|
||||||
Challenge,
|
Challenge,
|
||||||
ProtectedAction, SNComponent
|
SNComponent,
|
||||||
|
PermissionDialog,
|
||||||
|
DeinitSource,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import { getPlatformString } from '@/utils';
|
import { getPlatformString } from '@/utils';
|
||||||
@@ -27,17 +28,16 @@ import {
|
|||||||
import { AppState } from '@/ui_models/app_state';
|
import { AppState } from '@/ui_models/app_state';
|
||||||
import { SNWebCrypto } from '@standardnotes/sncrypto-web';
|
import { SNWebCrypto } from '@standardnotes/sncrypto-web';
|
||||||
import { Bridge } from '@/services/bridge';
|
import { Bridge } from '@/services/bridge';
|
||||||
import { DeinitSource } from '@standardnotes/snjs';
|
|
||||||
|
|
||||||
type WebServices = {
|
type WebServices = {
|
||||||
appState: AppState
|
appState: AppState;
|
||||||
desktopService: DesktopManager
|
desktopService: DesktopManager;
|
||||||
autolockService: AutolockService
|
autolockService: AutolockService;
|
||||||
archiveService: ArchiveManager
|
archiveService: ArchiveManager;
|
||||||
nativeExtService: NativeExtManager
|
nativeExtService: NativeExtManager;
|
||||||
statusManager: StatusManager
|
statusManager: StatusManager;
|
||||||
themeService: ThemeManager
|
themeService: ThemeManager;
|
||||||
keyboardService: KeyboardManager
|
keyboardService: KeyboardManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebApplication extends SNApplication {
|
export class WebApplication extends SNApplication {
|
||||||
@@ -78,7 +78,7 @@ export class WebApplication extends SNApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
deinit(source: DeinitSource) {
|
deinit(source: DeinitSource): void {
|
||||||
for (const service of Object.values(this.webServices)) {
|
for (const service of Object.values(this.webServices)) {
|
||||||
if ('deinit' in service) {
|
if ('deinit' in service) {
|
||||||
service.deinit?.(source);
|
service.deinit?.(source);
|
||||||
@@ -107,15 +107,15 @@ export class WebApplication extends SNApplication {
|
|||||||
this.componentManager!.presentPermissionsDialog = this.presentPermissionsDialog;
|
this.componentManager!.presentPermissionsDialog = this.presentPermissionsDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
setWebServices(services: WebServices) {
|
setWebServices(services: WebServices): void {
|
||||||
this.webServices = services;
|
this.webServices = services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAppState() {
|
public getAppState(): AppState {
|
||||||
return this.webServices.appState;
|
return this.webServices.appState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDesktopService() {
|
public getDesktopService(): DesktopManager {
|
||||||
return this.webServices.desktopService;
|
return this.webServices.desktopService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,46 +170,6 @@ export class WebApplication extends SNApplication {
|
|||||||
this.applicationElement.append(el);
|
this.applicationElement.append(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
async presentPrivilegesModal(
|
|
||||||
action: ProtectedAction,
|
|
||||||
onSuccess?: any,
|
|
||||||
onCancel?: any
|
|
||||||
) {
|
|
||||||
if (this.authenticationInProgress()) {
|
|
||||||
onCancel && onCancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const customSuccess = async () => {
|
|
||||||
onSuccess && await onSuccess();
|
|
||||||
this.currentAuthenticationElement = undefined;
|
|
||||||
};
|
|
||||||
const customCancel = async () => {
|
|
||||||
onCancel && await onCancel();
|
|
||||||
this.currentAuthenticationElement = undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const scope: any = this.scope!.$new(true);
|
|
||||||
scope.action = action;
|
|
||||||
scope.onSuccess = customSuccess;
|
|
||||||
scope.onCancel = customCancel;
|
|
||||||
scope.application = this;
|
|
||||||
const el = this.$compile!(`
|
|
||||||
<privileges-auth-modal application='application' action='action' on-success='onSuccess'
|
|
||||||
on-cancel='onCancel' class='sk-modal'></privileges-auth-modal>
|
|
||||||
`)(scope);
|
|
||||||
this.applicationElement.append(el);
|
|
||||||
|
|
||||||
this.currentAuthenticationElement = el;
|
|
||||||
}
|
|
||||||
|
|
||||||
presentPrivilegesManagementModal() {
|
|
||||||
const scope: any = this.scope!.$new(true);
|
|
||||||
scope.application = this;
|
|
||||||
const el = this.$compile!("<privileges-management-modal application='application' class='sk-modal'></privileges-management-modal>")(scope);
|
|
||||||
this.applicationElement.append(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
authenticationInProgress() {
|
authenticationInProgress() {
|
||||||
return this.currentAuthenticationElement != null;
|
return this.currentAuthenticationElement != null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
| {{ctrl.challenge.subheading}}
|
| {{ctrl.challenge.subheading}}
|
||||||
.sk-panel-section
|
.sk-panel-section
|
||||||
div(ng-repeat="prompt in ctrl.state.prompts track by prompt.id")
|
div(ng-repeat="prompt in ctrl.state.prompts track by prompt.id")
|
||||||
.sk-panel-row
|
.sk-panel-row(
|
||||||
|
ng-if="prompt.validation != ctrl.protectionsSessionValidation"
|
||||||
|
)
|
||||||
input.sk-input.contrast(
|
input.sk-input.contrast(
|
||||||
ng-model="ctrl.state.values[prompt.id].value"
|
ng-model="ctrl.state.values[prompt.id].value"
|
||||||
should-focus="$index == 0"
|
should-focus="$index == 0"
|
||||||
@@ -21,7 +23,17 @@
|
|||||||
ng-change="ctrl.onTextValueChange(prompt)"
|
ng-change="ctrl.onTextValueChange(prompt)"
|
||||||
ng-attr-type="{{prompt.secureTextEntry ? 'password' : 'text'}}",
|
ng-attr-type="{{prompt.secureTextEntry ? 'password' : 'text'}}",
|
||||||
ng-attr-placeholder="{{prompt.title}}"
|
ng-attr-placeholder="{{prompt.title}}"
|
||||||
)
|
)
|
||||||
|
.sk-horizontal-group(
|
||||||
|
ng-if="prompt.validation == ctrl.protectionsSessionValidation"
|
||||||
|
)
|
||||||
|
.sk-p.sk-bold Remember For
|
||||||
|
a.sk-a.info(
|
||||||
|
ng-repeat="option in ctrl.protectionsSessionDurations"
|
||||||
|
ng-class="{'boxed' : option.valueInSeconds == ctrl.state.values[prompt.id].value}"
|
||||||
|
ng-click="ctrl.onValueChange(prompt, option.valueInSeconds);"
|
||||||
|
)
|
||||||
|
| {{option.label}}
|
||||||
.sk-panel-row.centered
|
.sk-panel-row.centered
|
||||||
label.sk-label.danger(
|
label.sk-label.danger(
|
||||||
ng-if="ctrl.state.values[prompt.id].invalid"
|
ng-if="ctrl.state.values[prompt.id].invalid"
|
||||||
|
|||||||
@@ -5,45 +5,46 @@ import {
|
|||||||
removeFromArray,
|
removeFromArray,
|
||||||
Challenge,
|
Challenge,
|
||||||
ChallengeReason,
|
ChallengeReason,
|
||||||
ChallengePrompt
|
ChallengePrompt,
|
||||||
|
ChallengeValidation,
|
||||||
|
ProtectionSessionDurations,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import { WebDirective } from '@/types';
|
import { WebDirective } from '@/types';
|
||||||
import { confirmDialog } from '@/services/alertService';
|
import { confirmDialog } from '@/services/alertService';
|
||||||
import {
|
import { STRING_SIGN_OUT_CONFIRMATION } from '@/strings';
|
||||||
STRING_SIGN_OUT_CONFIRMATION,
|
|
||||||
} from '@/strings';
|
|
||||||
|
|
||||||
type InputValue = {
|
type InputValue = {
|
||||||
prompt: ChallengePrompt
|
prompt: ChallengePrompt;
|
||||||
value: string
|
value: string | number | boolean;
|
||||||
invalid: boolean
|
invalid: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
type Values = Record<number, InputValue>
|
type Values = Record<number, InputValue>;
|
||||||
|
|
||||||
type ChallengeModalState = {
|
type ChallengeModalState = {
|
||||||
prompts: ChallengePrompt[]
|
prompts: ChallengePrompt[];
|
||||||
values: Partial<Values>
|
values: Partial<Values>;
|
||||||
processing: boolean,
|
processing: boolean;
|
||||||
forgotPasscode: boolean,
|
forgotPasscode: boolean;
|
||||||
showForgotPasscodeLink: boolean,
|
showForgotPasscodeLink: boolean;
|
||||||
processingPrompts: ChallengePrompt[],
|
processingPrompts: ChallengePrompt[];
|
||||||
hasAccount: boolean,
|
hasAccount: boolean;
|
||||||
}
|
protectedNoteAccessDuration: number;
|
||||||
|
};
|
||||||
|
|
||||||
class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
class ChallengeModalCtrl extends PureViewCtrl<unknown, ChallengeModalState> {
|
||||||
private $element: JQLite
|
application!: WebApplication;
|
||||||
application!: WebApplication
|
challenge!: Challenge;
|
||||||
challenge!: Challenge
|
|
||||||
|
/** @template */
|
||||||
|
protectionsSessionDurations = ProtectionSessionDurations;
|
||||||
|
protectionsSessionValidation =
|
||||||
|
ChallengeValidation.ProtectionSessionDuration;
|
||||||
|
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor(
|
constructor(private $element: JQLite, $timeout: ng.ITimeoutService) {
|
||||||
$element: JQLite,
|
|
||||||
$timeout: ng.ITimeoutService
|
|
||||||
) {
|
|
||||||
super($timeout);
|
super($timeout);
|
||||||
this.$element = $element;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getState() {
|
getState() {
|
||||||
@@ -57,13 +58,13 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
for (const prompt of prompts) {
|
for (const prompt of prompts) {
|
||||||
values[prompt.id] = {
|
values[prompt.id] = {
|
||||||
prompt,
|
prompt,
|
||||||
value: '',
|
value: prompt.initialValue ?? '',
|
||||||
invalid: false
|
invalid: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const showForgotPasscodeLink = [
|
const showForgotPasscodeLink = [
|
||||||
ChallengeReason.ApplicationUnlock,
|
ChallengeReason.ApplicationUnlock,
|
||||||
ChallengeReason.Migration
|
ChallengeReason.Migration,
|
||||||
].includes(this.challenge.reason);
|
].includes(this.challenge.reason);
|
||||||
this.setState({
|
this.setState({
|
||||||
prompts,
|
prompts,
|
||||||
@@ -72,34 +73,32 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
forgotPasscode: false,
|
forgotPasscode: false,
|
||||||
showForgotPasscodeLink,
|
showForgotPasscodeLink,
|
||||||
hasAccount: this.application.hasAccount(),
|
hasAccount: this.application.hasAccount(),
|
||||||
processingPrompts: []
|
processingPrompts: [],
|
||||||
|
protectedNoteAccessDuration: ProtectionSessionDurations[0].valueInSeconds,
|
||||||
});
|
});
|
||||||
this.application.addChallengeObserver(
|
this.application.addChallengeObserver(this.challenge, {
|
||||||
this.challenge,
|
onValidValue: (value) => {
|
||||||
{
|
this.getState().values[value.prompt.id]!.invalid = false;
|
||||||
onValidValue: (value) => {
|
removeFromArray(this.state.processingPrompts, value.prompt);
|
||||||
this.getState().values[value.prompt.id]!.invalid = false;
|
this.reloadProcessingStatus();
|
||||||
|
},
|
||||||
|
onInvalidValue: (value) => {
|
||||||
|
this.getState().values[value.prompt.id]!.invalid = true;
|
||||||
|
/** If custom validation, treat all values together and not individually */
|
||||||
|
if (!value.prompt.validates) {
|
||||||
|
this.setState({ processingPrompts: [], processing: false });
|
||||||
|
} else {
|
||||||
removeFromArray(this.state.processingPrompts, value.prompt);
|
removeFromArray(this.state.processingPrompts, value.prompt);
|
||||||
this.reloadProcessingStatus();
|
this.reloadProcessingStatus();
|
||||||
},
|
}
|
||||||
onInvalidValue: (value) => {
|
},
|
||||||
this.getState().values[value.prompt.id]!.invalid = true;
|
onComplete: () => {
|
||||||
/** If custom validation, treat all values together and not individually */
|
this.dismiss();
|
||||||
if (!value.prompt.validates) {
|
},
|
||||||
this.setState({ processingPrompts: [], processing: false });
|
onCancel: () => {
|
||||||
} else {
|
this.dismiss();
|
||||||
removeFromArray(this.state.processingPrompts, value.prompt);
|
},
|
||||||
this.reloadProcessingStatus();
|
});
|
||||||
}
|
|
||||||
},
|
|
||||||
onComplete: () => {
|
|
||||||
this.dismiss();
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
|
||||||
this.dismiss();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit() {
|
deinit() {
|
||||||
@@ -110,18 +109,20 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
|
|
||||||
reloadProcessingStatus() {
|
reloadProcessingStatus() {
|
||||||
return this.setState({
|
return this.setState({
|
||||||
processing: this.state.processingPrompts.length > 0
|
processing: this.state.processingPrompts.length > 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async destroyLocalData() {
|
async destroyLocalData() {
|
||||||
if (await confirmDialog({
|
if (
|
||||||
text: STRING_SIGN_OUT_CONFIRMATION,
|
await confirmDialog({
|
||||||
confirmButtonStyle: "danger"
|
text: STRING_SIGN_OUT_CONFIRMATION,
|
||||||
})) {
|
confirmButtonStyle: 'danger',
|
||||||
|
})
|
||||||
|
) {
|
||||||
await this.application.signOut();
|
await this.application.signOut();
|
||||||
this.dismiss();
|
this.dismiss();
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @template */
|
/** @template */
|
||||||
@@ -133,7 +134,7 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
|
|
||||||
onForgotPasscodeClick() {
|
onForgotPasscodeClick() {
|
||||||
this.setState({
|
this.setState({
|
||||||
forgotPasscode: true
|
forgotPasscode: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,15 +144,22 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
this.setState({ values });
|
this.setState({ values });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onValueChange(prompt: ChallengePrompt, value: number) {
|
||||||
|
const values = this.state.values;
|
||||||
|
values[prompt.id]!.invalid = false;
|
||||||
|
values[prompt.id]!.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
validate() {
|
validate() {
|
||||||
const failed = [];
|
let failed = 0;
|
||||||
for (const prompt of this.getState().prompts) {
|
for (const prompt of this.state.prompts) {
|
||||||
const value = this.getState().values[prompt.id];
|
const value = this.state.values[prompt.id]!;
|
||||||
if (!value || value.value.length === 0) {
|
if (typeof value.value === 'string' && value.value.length === 0) {
|
||||||
this.getState().values[prompt.id]!.invalid = true;
|
this.state.values[prompt.id]!.invalid = true;
|
||||||
|
failed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return failed.length === 0;
|
return failed === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
@@ -161,15 +169,15 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
await this.setState({ processing: true });
|
await this.setState({ processing: true });
|
||||||
const values: ChallengeValue[] = [];
|
const values: ChallengeValue[] = [];
|
||||||
for (const inputValue of Object.values(this.getState().values)) {
|
for (const inputValue of Object.values(this.getState().values)) {
|
||||||
const rawValue = inputValue!!.value;
|
const rawValue = inputValue!.value;
|
||||||
const value = new ChallengeValue(inputValue!.prompt, rawValue);
|
const value = new ChallengeValue(inputValue!.prompt, rawValue);
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
const processingPrompts = values.map((v) => v.prompt);
|
const processingPrompts = values.map((v) => v.prompt);
|
||||||
await this.setState({
|
await this.setState({
|
||||||
processingPrompts: processingPrompts,
|
processingPrompts: processingPrompts,
|
||||||
processing: processingPrompts.length > 0
|
processing: processingPrompts.length > 0,
|
||||||
})
|
});
|
||||||
/**
|
/**
|
||||||
* Unfortunately neccessary to wait 50ms so that the above setState call completely
|
* Unfortunately neccessary to wait 50ms so that the above setState call completely
|
||||||
* updates the UI to change processing state, before we enter into UI blocking operation
|
* updates the UI to change processing state, before we enter into UI blocking operation
|
||||||
@@ -181,7 +189,7 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> {
|
|||||||
} else {
|
} else {
|
||||||
this.setState({ processing: false });
|
this.setState({ processing: false });
|
||||||
}
|
}
|
||||||
}, 50)
|
}, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
dismiss() {
|
dismiss() {
|
||||||
@@ -202,7 +210,7 @@ export class ChallengeModal extends WebDirective {
|
|||||||
this.bindToController = true;
|
this.bindToController = true;
|
||||||
this.scope = {
|
this.scope = {
|
||||||
challenge: '=',
|
challenge: '=',
|
||||||
application: '='
|
application: '=',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
isPayloadSourceRetrieved,
|
isPayloadSourceRetrieved,
|
||||||
isPayloadSourceInternalChange,
|
isPayloadSourceInternalChange,
|
||||||
ContentType,
|
ContentType,
|
||||||
ProtectedAction,
|
|
||||||
SNComponent,
|
SNComponent,
|
||||||
SNNote,
|
SNNote,
|
||||||
SNTag,
|
SNTag,
|
||||||
@@ -24,7 +23,7 @@ import { isDesktopApplication } from '@/utils';
|
|||||||
import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager';
|
import { KeyboardModifier, KeyboardKey } from '@/services/keyboardManager';
|
||||||
import template from './editor-view.pug';
|
import template from './editor-view.pug';
|
||||||
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl';
|
||||||
import { AppStateEvent, EventSource } from '@/ui_models/app_state';
|
import { EventSource } from '@/ui_models/app_state';
|
||||||
import {
|
import {
|
||||||
STRING_DELETED_NOTE,
|
STRING_DELETED_NOTE,
|
||||||
STRING_INVALID_NOTE,
|
STRING_INVALID_NOTE,
|
||||||
@@ -85,7 +84,7 @@ type EditorState = {
|
|||||||
* then re-initialized. Used when reloading spellcheck status. */
|
* then re-initialized. Used when reloading spellcheck status. */
|
||||||
textareaUnloading: boolean
|
textareaUnloading: boolean
|
||||||
/** Fields that can be directly mutated by the template */
|
/** Fields that can be directly mutated by the template */
|
||||||
mutable: {}
|
mutable: any
|
||||||
}
|
}
|
||||||
|
|
||||||
type EditorValues = {
|
type EditorValues = {
|
||||||
@@ -98,7 +97,7 @@ function sortAlphabetically(array: SNComponent[]): SNComponent[] {
|
|||||||
return array.sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1);
|
return array.sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
class EditorViewCtrl extends PureViewCtrl<unknown, EditorState> {
|
||||||
/** Passed through template */
|
/** Passed through template */
|
||||||
readonly application!: WebApplication
|
readonly application!: WebApplication
|
||||||
readonly editor!: Editor
|
readonly editor!: Editor
|
||||||
@@ -248,7 +247,7 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
|||||||
case ApplicationEvent.HighLatencySync:
|
case ApplicationEvent.HighLatencySync:
|
||||||
this.setState({ syncTakingTooLong: true });
|
this.setState({ syncTakingTooLong: true });
|
||||||
break;
|
break;
|
||||||
case ApplicationEvent.CompletedFullSync:
|
case ApplicationEvent.CompletedFullSync: {
|
||||||
this.setState({ syncTakingTooLong: false });
|
this.setState({ syncTakingTooLong: false });
|
||||||
const isInErrorState = this.state.saveError;
|
const isInErrorState = this.state.saveError;
|
||||||
/** if we're still dirty, don't change status, a sync is likely upcoming. */
|
/** if we're still dirty, don't change status, a sync is likely upcoming. */
|
||||||
@@ -256,6 +255,7 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
|||||||
this.showAllChangesSavedStatus();
|
this.showAllChangesSavedStatus();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ApplicationEvent.FailedSync:
|
case ApplicationEvent.FailedSync:
|
||||||
/**
|
/**
|
||||||
* Only show error status in editor if the note is dirty.
|
* Only show error status in editor if the note is dirty.
|
||||||
@@ -601,10 +601,12 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
|||||||
this.setMenuState('showOptionsMenu', false);
|
this.setMenuState('showOptionsMenu', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
onTitleFocus() {
|
onTitleFocus() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
onTitleBlur() {
|
onTitleBlur() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -627,50 +629,35 @@ class EditorViewCtrl extends PureViewCtrl<{}, EditorState> {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const run = async () => {
|
if (this.note.locked) {
|
||||||
if (this.note.locked) {
|
this.application.alertService!.alert(
|
||||||
this.application.alertService!.alert(
|
STRING_DELETE_LOCKED_ATTEMPT
|
||||||
STRING_DELETE_LOCKED_ATTEMPT
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const title = this.note.safeTitle().length
|
|
||||||
? `'${this.note.title}'`
|
|
||||||
: "this note";
|
|
||||||
const text = StringDeleteNote(
|
|
||||||
title,
|
|
||||||
permanently
|
|
||||||
);
|
);
|
||||||
if (await confirmDialog({
|
return;
|
||||||
text,
|
}
|
||||||
confirmButtonStyle: 'danger'
|
const title = this.note.safeTitle().length
|
||||||
})) {
|
? `'${this.note.title}'`
|
||||||
if (permanently) {
|
: "this note";
|
||||||
this.performNoteDeletion(this.note);
|
const text = StringDeleteNote(
|
||||||
} else {
|
title,
|
||||||
this.saveNote(
|
permanently
|
||||||
true,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
(mutator) => {
|
|
||||||
mutator.trashed = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const requiresPrivilege = await this.application.privilegesService!.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.DeleteNote
|
|
||||||
);
|
);
|
||||||
if (requiresPrivilege) {
|
if (await confirmDialog({
|
||||||
this.application.presentPrivilegesModal(
|
text,
|
||||||
ProtectedAction.DeleteNote,
|
confirmButtonStyle: 'danger'
|
||||||
() => {
|
})) {
|
||||||
run();
|
if (permanently) {
|
||||||
}
|
this.performNoteDeletion(this.note);
|
||||||
);
|
} else {
|
||||||
} else {
|
this.saveNote(
|
||||||
run();
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
(mutator) => {
|
||||||
|
mutator.trashed = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { dateToLocalizedString, preventRefreshing } from '@/utils';
|
|||||||
import {
|
import {
|
||||||
ApplicationEvent,
|
ApplicationEvent,
|
||||||
SyncQueueStrategy,
|
SyncQueueStrategy,
|
||||||
ProtectedAction,
|
|
||||||
ContentType,
|
ContentType,
|
||||||
SNComponent,
|
SNComponent,
|
||||||
SNTheme,
|
SNTheme,
|
||||||
@@ -44,7 +43,7 @@ type DockShortcut = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FooterViewCtrl extends PureViewCtrl<{}, {
|
class FooterViewCtrl extends PureViewCtrl<unknown, {
|
||||||
outOfSync: boolean;
|
outOfSync: boolean;
|
||||||
hasPasscode: boolean;
|
hasPasscode: boolean;
|
||||||
dataUpgradeAvailable: boolean;
|
dataUpgradeAvailable: boolean;
|
||||||
@@ -207,7 +206,7 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
|||||||
case AppStateEvent.BeganBackupDownload:
|
case AppStateEvent.BeganBackupDownload:
|
||||||
statusService.setMessage("Saving local backup…");
|
statusService.setMessage("Saving local backup…");
|
||||||
break;
|
break;
|
||||||
case AppStateEvent.EndedBackupDownload:
|
case AppStateEvent.EndedBackupDownload: {
|
||||||
const successMessage = "Successfully saved backup.";
|
const successMessage = "Successfully saved backup.";
|
||||||
const errorMessage = "Unable to save local backup."
|
const errorMessage = "Unable to save local backup."
|
||||||
statusService.setMessage(data.success ? successMessage : errorMessage);
|
statusService.setMessage(data.success ? successMessage : errorMessage);
|
||||||
@@ -222,6 +221,7 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
|||||||
}
|
}
|
||||||
}, twoSeconds);
|
}, twoSeconds);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,28 +544,9 @@ class FooterViewCtrl extends PureViewCtrl<{}, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async selectRoom(room: SNComponent) {
|
async selectRoom(room: SNComponent) {
|
||||||
const run = () => {
|
this.$timeout(() => {
|
||||||
this.$timeout(() => {
|
this.roomShowState[room.uuid] = !this.roomShowState[room.uuid];
|
||||||
this.roomShowState[room.uuid] = !this.roomShowState[room.uuid];
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.roomShowState[room.uuid]) {
|
|
||||||
const requiresPrivilege = await this.application.privilegesService!
|
|
||||||
.actionRequiresPrivilege(
|
|
||||||
ProtectedAction.ManageExtensions
|
|
||||||
);
|
|
||||||
if (requiresPrivilege) {
|
|
||||||
this.application.presentPrivilegesModal(
|
|
||||||
ProtectedAction.ManageExtensions,
|
|
||||||
run
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
displayBetaDialog() {
|
displayBetaDialog() {
|
||||||
|
|||||||
@@ -168,10 +168,6 @@
|
|||||||
ng-click="self.openSessionsModal()"
|
ng-click="self.openSessionsModal()"
|
||||||
ng-if="self.state.showSessions"
|
ng-if="self.state.showSessions"
|
||||||
) Manage Sessions
|
) Manage Sessions
|
||||||
a.sk-a.info.sk-panel-row.condensed(
|
|
||||||
ng-click="self.openPrivilegesModal('')",
|
|
||||||
ng-show='self.state.user'
|
|
||||||
) Manage Privileges
|
|
||||||
.sk-panel-section
|
.sk-panel-section
|
||||||
.sk-panel-section-title Encryption
|
.sk-panel-section-title Encryption
|
||||||
.sk-panel-section-subtitle.info(ng-if='self.state.encryptionEnabled')
|
.sk-panel-section-subtitle.info(ng-if='self.state.encryptionEnabled')
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
"@types/mocha": "^7.0.2",
|
"@types/mocha": "^7.0.2",
|
||||||
"@types/pug": "^2.0.4",
|
"@types/pug": "^2.0.4",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.23.0",
|
"@typescript-eslint/eslint-plugin": "^3.10.1",
|
||||||
"@typescript-eslint/parser": "^2.23.0",
|
"@typescript-eslint/parser": "^3.10.1",
|
||||||
"angular": "^1.8.2",
|
"angular": "^1.8.2",
|
||||||
"apply-loader": "^2.0.0",
|
"apply-loader": "^2.0.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
@@ -71,9 +71,12 @@
|
|||||||
"@reach/alert-dialog": "^0.12.1",
|
"@reach/alert-dialog": "^0.12.1",
|
||||||
"@reach/dialog": "^0.12.1",
|
"@reach/dialog": "^0.12.1",
|
||||||
"@standardnotes/sncrypto-web": "^1.2.9",
|
"@standardnotes/sncrypto-web": "^1.2.9",
|
||||||
"@standardnotes/snjs": "^2.0.35",
|
"@standardnotes/snjs": "^2.0.41",
|
||||||
"babel-loader": "^8.2.2",
|
"babel-loader": "^8.2.2",
|
||||||
"mobx": "^6.0.4",
|
"mobx": "^6.0.4",
|
||||||
"preact": "^10.5.7"
|
"preact": "^10.5.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
67
yarn.lock
67
yarn.lock
@@ -1045,10 +1045,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.35":
|
"@standardnotes/snjs@^2.0.41":
|
||||||
version "2.0.35"
|
version "2.0.41"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.35.tgz#9e9c3058ebbfc9af7a5fc3ae18497f02a9b1e71b"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.41.tgz#131f3a206b220be5359c43963c47b1929b92f037"
|
||||||
integrity sha512-uA4HXorgiV8yFGN1dtO52istUudnc3ZzEQiFLgf0bkKvA0wH3Xt+R9bBviYAdIBkTBKHCyGsBdsCiKr1QS/X9g==
|
integrity sha512-/6hoBcb/Ib8voqwk1YLVTAM6L2ZJV/AZDXJz/oEKY9cjO0onFMbl0T+AAWEal1d6zojyjC4Wv6Pc9fkNInvBSQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/sncrypto-common" "^1.2.9"
|
"@standardnotes/sncrypto-common" "^1.2.9"
|
||||||
|
|
||||||
@@ -1188,49 +1188,66 @@
|
|||||||
"@types/webpack-sources" "*"
|
"@types/webpack-sources" "*"
|
||||||
source-map "^0.6.0"
|
source-map "^0.6.0"
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@^2.23.0":
|
"@typescript-eslint/eslint-plugin@^3.10.1":
|
||||||
version "2.34.0"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f"
|
||||||
integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==
|
integrity sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/experimental-utils" "2.34.0"
|
"@typescript-eslint/experimental-utils" "3.10.1"
|
||||||
|
debug "^4.1.1"
|
||||||
functional-red-black-tree "^1.0.1"
|
functional-red-black-tree "^1.0.1"
|
||||||
regexpp "^3.0.0"
|
regexpp "^3.0.0"
|
||||||
|
semver "^7.3.2"
|
||||||
tsutils "^3.17.1"
|
tsutils "^3.17.1"
|
||||||
|
|
||||||
"@typescript-eslint/experimental-utils@2.34.0":
|
"@typescript-eslint/experimental-utils@3.10.1":
|
||||||
version "2.34.0"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
|
||||||
integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==
|
integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json-schema" "^7.0.3"
|
"@types/json-schema" "^7.0.3"
|
||||||
"@typescript-eslint/typescript-estree" "2.34.0"
|
"@typescript-eslint/types" "3.10.1"
|
||||||
|
"@typescript-eslint/typescript-estree" "3.10.1"
|
||||||
eslint-scope "^5.0.0"
|
eslint-scope "^5.0.0"
|
||||||
eslint-utils "^2.0.0"
|
eslint-utils "^2.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@^2.23.0":
|
"@typescript-eslint/parser@^3.10.1":
|
||||||
version "2.34.0"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467"
|
||||||
integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==
|
integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/eslint-visitor-keys" "^1.0.0"
|
"@types/eslint-visitor-keys" "^1.0.0"
|
||||||
"@typescript-eslint/experimental-utils" "2.34.0"
|
"@typescript-eslint/experimental-utils" "3.10.1"
|
||||||
"@typescript-eslint/typescript-estree" "2.34.0"
|
"@typescript-eslint/types" "3.10.1"
|
||||||
|
"@typescript-eslint/typescript-estree" "3.10.1"
|
||||||
eslint-visitor-keys "^1.1.0"
|
eslint-visitor-keys "^1.1.0"
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@2.34.0":
|
"@typescript-eslint/types@3.10.1":
|
||||||
version "2.34.0"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
|
||||||
integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==
|
integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree@3.10.1":
|
||||||
|
version "3.10.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853"
|
||||||
|
integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@typescript-eslint/types" "3.10.1"
|
||||||
|
"@typescript-eslint/visitor-keys" "3.10.1"
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
eslint-visitor-keys "^1.1.0"
|
|
||||||
glob "^7.1.6"
|
glob "^7.1.6"
|
||||||
is-glob "^4.0.1"
|
is-glob "^4.0.1"
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
tsutils "^3.17.1"
|
tsutils "^3.17.1"
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys@3.10.1":
|
||||||
|
version "3.10.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931"
|
||||||
|
integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==
|
||||||
|
dependencies:
|
||||||
|
eslint-visitor-keys "^1.1.0"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.9.0":
|
"@webassemblyjs/ast@1.9.0":
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
||||||
|
|||||||
Reference in New Issue
Block a user