WIP
This commit is contained in:
@@ -112,17 +112,13 @@ class EditorCtrl extends PureCtrl {
|
||||
return;
|
||||
}
|
||||
if (eventName === ApplicationEvents.HighLatencySync) {
|
||||
this.setState({
|
||||
syncTakingTooLong: true
|
||||
});
|
||||
this.setState({ syncTakingTooLong: true });
|
||||
} else if (eventName === ApplicationEvents.CompletedSync) {
|
||||
this.setState({
|
||||
syncTakingTooLong: false
|
||||
});
|
||||
this.setState({ syncTakingTooLong: false });
|
||||
if (this.state.note.dirty) {
|
||||
/** if we're still dirty, don't change status, a sync is likely upcoming. */
|
||||
} else {
|
||||
const saved = this.state.note.updated_at > this.state.note.lastSyncBegan;
|
||||
const saved = this.state.note.lastSyncEnd > this.state.note.lastSyncBegan;
|
||||
const isInErrorState = this.state.saveError;
|
||||
if (isInErrorState || saved) {
|
||||
this.showAllChangesSavedStatus();
|
||||
@@ -792,8 +788,8 @@ class EditorCtrl extends PureCtrl {
|
||||
this.reloadFont();
|
||||
|
||||
if (
|
||||
this.state.marginResizersEnabled &&
|
||||
this.leftPanelPuppet.ready &&
|
||||
this.state.marginResizersEnabled &&
|
||||
this.leftPanelPuppet.ready &&
|
||||
this.rightPanelPuppet.ready
|
||||
) {
|
||||
const width = this.preferencesManager.getValue(
|
||||
|
||||
@@ -59,7 +59,6 @@ class FooterCtrl extends PureCtrl {
|
||||
});
|
||||
this.user = this.application.getUser();
|
||||
this.updateOfflineStatus();
|
||||
this.addAppEventObserver();
|
||||
this.findErrors();
|
||||
this.streamItems();
|
||||
this.registerComponentHandler();
|
||||
@@ -111,15 +110,14 @@ class FooterCtrl extends PureCtrl {
|
||||
|
||||
/** @override */
|
||||
onApplicationEvent(eventName) {
|
||||
if (eventName === ApplicationEvents.LoadedLocalData) {
|
||||
if (this.offline && this.application.getNoteCount() === 0) {
|
||||
this.showAccountMenu = true;
|
||||
}
|
||||
} else if (eventName === ApplicationEvents.EnteredOutOfSync) {
|
||||
if (eventName === ApplicationEvents.EnteredOutOfSync) {
|
||||
this.outOfSync = true;
|
||||
} else if (eventName === ApplicationEvents.ExitedOutOfSync) {
|
||||
this.outOfSync = false;
|
||||
} else if (eventName === ApplicationEvents.CompletedSync) {
|
||||
if (this.offline && this.application.getNoteCount() === 0) {
|
||||
this.showAccountMenu = true;
|
||||
}
|
||||
this.syncUpdated();
|
||||
this.findErrors();
|
||||
this.updateOfflineStatus();
|
||||
|
||||
@@ -113,6 +113,9 @@ class NotesCtrl extends PureCtrl {
|
||||
this.createDummyOnSynCompletionIfNoNotes = true;
|
||||
}
|
||||
} else if (eventName === ApplicationEvents.CompletedSync) {
|
||||
if (this.state.notes.length === 0) {
|
||||
this.createNewNote();
|
||||
}
|
||||
if (this.createDummyOnSynCompletionIfNoNotes && this.state.notes.length === 0) {
|
||||
this.createDummyOnSynCompletionIfNoNotes = false;
|
||||
this.createNewNote();
|
||||
|
||||
@@ -37,7 +37,7 @@ class RootCtrl extends PureCtrl {
|
||||
this.themeManager = themeManager;
|
||||
this.platformString = getPlatformString();
|
||||
this.state = {
|
||||
needsUnlock: true,
|
||||
ready: false,
|
||||
appClass: ''
|
||||
};
|
||||
this.loadApplication();
|
||||
@@ -86,17 +86,18 @@ class RootCtrl extends PureCtrl {
|
||||
}
|
||||
});
|
||||
await this.application.launch();
|
||||
this.setState({ ready: true });
|
||||
// this.addSyncStatusObserver();
|
||||
// this.addSyncEventHandler();
|
||||
}
|
||||
|
||||
|
||||
onUpdateAvailable() {
|
||||
this.$rootScope.$broadcast('new-update-available');
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
async onApplicationEvent(eventName) {
|
||||
if (eventName === ApplicationEvents.ApplicationUnlocked) {
|
||||
if (eventName === ApplicationEvents.ApplicationUnlocked) {
|
||||
this.setState({ needsUnlock: false });
|
||||
this.application.componentManager.setDesktopManager(this.desktopManager);
|
||||
this.application.registerService(this.themeManager);
|
||||
|
||||
@@ -53,7 +53,9 @@ class AccountMenuCtrl extends PureCtrl {
|
||||
passcodeAutoLockOptions: this.lockManager.getAutoLockIntervalOptions(),
|
||||
formData: {
|
||||
mergeLocal: true,
|
||||
ephemeral: false
|
||||
ephemeral: false,
|
||||
email: "b@bitar.io",
|
||||
user_password: "password"
|
||||
},
|
||||
mutable: {}
|
||||
};
|
||||
@@ -182,7 +184,7 @@ class AccountMenuCtrl extends PureCtrl {
|
||||
password: this.state.formData.user_password,
|
||||
strict: this.state.formData.strictSignin,
|
||||
ephemeral: this.state.formData.ephemeral,
|
||||
mfaKeyPath: this.state.formData.mfa.payload.mfa_key,
|
||||
mfaKeyPath: this.state.formData.mfa && this.state.formData.mfa.payload.mfa_key,
|
||||
mfaCode: this.state.formData.userMfaCode,
|
||||
mergeLocal: this.state.formData.mergeLocal
|
||||
});
|
||||
@@ -314,7 +316,7 @@ class AccountMenuCtrl extends PureCtrl {
|
||||
* https://github.com/standardnotes/desktop/issues/131
|
||||
*/
|
||||
async rewriteDatabase({ alternateUuids } = {}) {
|
||||
await this.application.destroyDatabase();
|
||||
await this.application.clearDatabase();
|
||||
await this.application.markAllItemsAsNeedingSync({ alternateUuids });
|
||||
}
|
||||
|
||||
@@ -324,7 +326,6 @@ class AccountMenuCtrl extends PureCtrl {
|
||||
destructive: true,
|
||||
onConfirm: async () => {
|
||||
await this.application.signOut();
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,31 +4,24 @@ import { isNullOrUndefined } from '../../utils';
|
||||
|
||||
const DEFAULT_CONTINUE_TITLE = "Continue";
|
||||
const Steps = {
|
||||
IntroStep: 0,
|
||||
BackupStep: 1,
|
||||
SignoutStep: 2,
|
||||
PasswordStep: 3,
|
||||
SyncStep: 4,
|
||||
FinishStep: 5
|
||||
FinishStep: 5
|
||||
};
|
||||
|
||||
class PasswordWizardCtrl {
|
||||
class PasswordWizardCtrl {
|
||||
/* @ngInject */
|
||||
constructor(
|
||||
$element,
|
||||
$scope,
|
||||
$timeout,
|
||||
archiveManager
|
||||
$timeout
|
||||
) {
|
||||
this.$element = $element;
|
||||
this.$timeout = $timeout;
|
||||
this.$scope = $scope;
|
||||
this.archiveManager = archiveManager;
|
||||
this.registerWindowUnloadStopper();
|
||||
}
|
||||
|
||||
|
||||
$onInit() {
|
||||
this.syncStatus = this.application.getSyncStatus();
|
||||
this.formData = {};
|
||||
this.configureDefaults();
|
||||
}
|
||||
@@ -44,7 +37,7 @@ class PasswordWizardCtrl {
|
||||
this.continueTitle = DEFAULT_CONTINUE_TITLE;
|
||||
this.step = Steps.IntroStep;
|
||||
}
|
||||
|
||||
|
||||
/** Confirms with user before closing tab */
|
||||
registerWindowUnloadStopper() {
|
||||
window.onbeforeunload = (e) => {
|
||||
@@ -57,18 +50,12 @@ class PasswordWizardCtrl {
|
||||
|
||||
titleForStep(step) {
|
||||
switch (step) {
|
||||
case Steps.BackupStep:
|
||||
return "Download a backup of your data";
|
||||
case Steps.SignoutStep:
|
||||
return "Sign out of all your devices";
|
||||
case Steps.PasswordStep:
|
||||
return this.changePassword
|
||||
? "Password information"
|
||||
return this.changePassword
|
||||
? "Password information"
|
||||
: "Enter your current password";
|
||||
case Steps.SyncStep:
|
||||
return "Encrypt and sync data with new keys";
|
||||
case Steps.FinishStep:
|
||||
return "Sign back in to your devices";
|
||||
return "Success";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -112,9 +99,7 @@ class PasswordWizardCtrl {
|
||||
}
|
||||
|
||||
async initializeStep(step) {
|
||||
if (step === Steps.SyncStep) {
|
||||
await this.initializeSyncingStep();
|
||||
} else if (step === Steps.FinishStep) {
|
||||
if (step === Steps.FinishStep) {
|
||||
this.continueTitle = "Finish";
|
||||
}
|
||||
}
|
||||
@@ -123,11 +108,10 @@ class PasswordWizardCtrl {
|
||||
this.lockContinue = true;
|
||||
this.formData.status = "Processing encryption keys...";
|
||||
this.formData.processing = true;
|
||||
|
||||
const passwordSuccess = await this.processPasswordChange();
|
||||
this.formData.statusError = !passwordSuccess;
|
||||
this.formData.processing = passwordSuccess;
|
||||
if(!passwordSuccess) {
|
||||
if (!passwordSuccess) {
|
||||
this.formData.status = "Unable to process your password. Please try again.";
|
||||
return;
|
||||
}
|
||||
@@ -143,74 +127,70 @@ class PasswordWizardCtrl {
|
||||
const currentPassword = this.formData.currentPassword;
|
||||
const newPass = this.securityUpdate ? currentPassword : this.formData.newPassword;
|
||||
if (!currentPassword || currentPassword.length === 0) {
|
||||
this.application.alertManager.alert({
|
||||
text: "Please enter your current password."
|
||||
this.application.alertManager.alert({
|
||||
text: "Please enter your current password."
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.changePassword) {
|
||||
if (!newPass || newPass.length === 0) {
|
||||
this.application.alertManager.alert({
|
||||
text: "Please enter a new password."
|
||||
this.application.alertManager.alert({
|
||||
text: "Please enter a new password."
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (newPass !== this.formData.newPasswordConfirmation) {
|
||||
this.application.alertManager.alert({
|
||||
text: "Your new password does not match its confirmation."
|
||||
this.application.alertManager.alert({
|
||||
text: "Your new password does not match its confirmation."
|
||||
});
|
||||
this.formData.status = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!this.application.getUser().email) {
|
||||
this.application.alertManager.alert({
|
||||
text: "We don't have your email stored. Please log out then log back in to fix this issue."
|
||||
this.application.alertManager.alert({
|
||||
text: "We don't have your email stored. Please log out then log back in to fix this issue."
|
||||
});
|
||||
this.formData.status = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Validate current password */
|
||||
const key = await this.application.validateAccountPassword({
|
||||
const key = await this.application.validateAccountPassword({
|
||||
password: this.formData.currentPassword
|
||||
});
|
||||
if (key) {
|
||||
this.currentServerPassword = key.serverPassword;
|
||||
} else {
|
||||
this.application.alertManager.alert({
|
||||
text: "The current password you entered is not correct. Please try again."
|
||||
this.application.alertManager.alert({
|
||||
text: "The current password you entered is not correct. Please try again."
|
||||
});
|
||||
}
|
||||
return !isNullOrUndefined(key);
|
||||
}
|
||||
|
||||
async processPasswordChange() {
|
||||
const newPassword = this.securityUpdate
|
||||
? this.formData.currentPassword
|
||||
const newPassword = this.securityUpdate
|
||||
? this.formData.currentPassword
|
||||
: this.formData.newPassword;
|
||||
|
||||
const response = await this.application.changePassword({
|
||||
email: this.application.getUser().email,
|
||||
currentPassword: this.formData.currentPassword,
|
||||
email: this.application.getUser().email,
|
||||
currentPassword: this.formData.currentPassword,
|
||||
newPassword: newPassword
|
||||
});
|
||||
if (response.error) {
|
||||
this.application.alertManager.alert({
|
||||
text: response.error.message
|
||||
? response.error.message
|
||||
: "There was an error changing your password. Please try again."
|
||||
});
|
||||
return false;
|
||||
this.application.alertManager.alert({
|
||||
text: response.error.message
|
||||
? response.error.message
|
||||
: "There was an error changing your password. Please try again."
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
downloadBackup(encrypted) {
|
||||
this.archiveManager.downloadBackup(encrypted);
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
if (this.lockContinue) {
|
||||
this.application.alertManager.alert({
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { isDesktopApplication, dictToArray } from '@/utils';
|
||||
import { SFPredicate, ContentTypes, CreateMaxPayloadFromAnyObject } from 'snjs';
|
||||
import { AppStateEvents } from '@/state';
|
||||
|
||||
const STREAM_ITEMS_PERMISSION = 'stream-items';
|
||||
|
||||
@@ -11,18 +10,29 @@ export class NativeExtManager {
|
||||
this.application = application;
|
||||
this.extManagerId = 'org.standardnotes.extensions-manager';
|
||||
this.batchManagerId = 'org.standardnotes.batch-manager';
|
||||
this.systemExtensions = [];
|
||||
this.resolveExtensionsManager();
|
||||
this.resolveBatchManager();
|
||||
|
||||
application.onUnlock(() => {
|
||||
this.resolveExtensionsManager();
|
||||
this.resolveBatchManager();
|
||||
this.reload();
|
||||
this.streamChanges();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
isSystemExtension(extension) {
|
||||
return this.systemExtensions.includes(extension.uuid);
|
||||
return this.nativeExtIds.includes(extension.uuid);
|
||||
}
|
||||
|
||||
streamChanges() {
|
||||
this.application.streamItems({
|
||||
contentType: ContentTypes.Component,
|
||||
stream: () => {
|
||||
this.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.nativeExtIds = [];
|
||||
// this.resolveExtensionsManager();
|
||||
// this.resolveBatchManager();
|
||||
}
|
||||
|
||||
extensionsManagerTemplatePayload() {
|
||||
@@ -76,7 +86,7 @@ export class NativeExtManager {
|
||||
predicate: predicate,
|
||||
createPayload: this.extensionsManagerTemplatePayload()
|
||||
});
|
||||
this.systemExtensions.push(extensionsManager.uuid);
|
||||
this.nativeExtIds.push(extensionsManager.uuid);
|
||||
let needsSync = false;
|
||||
if (isDesktopApplication()) {
|
||||
if (!extensionsManager.local_url) {
|
||||
@@ -144,7 +154,7 @@ export class NativeExtManager {
|
||||
predicate: predicate,
|
||||
createPayload: this.batchManagerTemplatePayload()
|
||||
});
|
||||
this.systemExtensions.push(batchManager.uuid);
|
||||
this.nativeExtIds.push(batchManager.uuid);
|
||||
let needsSync = false;
|
||||
if (isDesktopApplication()) {
|
||||
if (!batchManager.local_url) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SFPredicate, CreateMaxPayloadFromAnyObject } from 'snjs';
|
||||
import { SFPredicate, ContentTypes, CreateMaxPayloadFromAnyObject } from 'snjs';
|
||||
|
||||
export const PrefKeys = {
|
||||
TagsPanelWidth: 'tagsPanelWidth',
|
||||
@@ -33,24 +33,26 @@ export class PreferencesManager {
|
||||
|
||||
streamPreferences() {
|
||||
this.application.streamItems({
|
||||
contentType: 'SN|UserPreferences',
|
||||
contentType: ContentTypes.UserPrefs,
|
||||
stream: () => {
|
||||
this.preferencesDidChange();
|
||||
this.loadSingleton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadSingleton() {
|
||||
const contentType = 'SN|UserPreferences';
|
||||
const contentType = ContentTypes.UserPrefs;
|
||||
const predicate = new SFPredicate('content_type', '=', contentType);
|
||||
this.userPreferences = await this.application.singletonManager.findOrCreateSingleton({
|
||||
predicate: predicate,
|
||||
createPayload: CreateMaxPayloadFromAnyObject({
|
||||
object: {
|
||||
content_type: contentType
|
||||
content_type: contentType,
|
||||
content: {}
|
||||
}
|
||||
})
|
||||
});
|
||||
this.preferencesDidChange();
|
||||
}
|
||||
|
||||
preferencesDidChange() {
|
||||
|
||||
@@ -8,125 +8,38 @@
|
||||
.sk-panel-header-title {{ctrl.title}}
|
||||
a.sk-a.info.close-button(ng-click='ctrl.dismiss()') Close
|
||||
.sk-panel-content
|
||||
div(ng-if='ctrl.step == 0')
|
||||
div(ng-if='ctrl.changePassword')
|
||||
p.sk-p.sk-panel-row
|
||||
| Changing your password involves changing your encryption key,
|
||||
| which requires your data to be re-encrypted and synced.
|
||||
| If you have many items, syncing your data can take several minutes.
|
||||
p.sk-p.sk-panel-row
|
||||
| You must keep the application window open during this process.
|
||||
div(ng-if='ctrl.securityUpdate')
|
||||
p.sk-p.sk-panel-row
|
||||
| A new update is available for your account. Updates address
|
||||
| improvements and enhancements to our security specification.
|
||||
| This process will guide you through the update, and perform the
|
||||
| steps necessary with your supervision.
|
||||
.sk-panel-row
|
||||
.sk-panel-column
|
||||
p.sk-p For more information about account updates, please visit
|
||||
a.sk-a.info(
|
||||
href='https://standardnotes.org/help/security',
|
||||
rel='noopener',
|
||||
target='_blank'
|
||||
) standardnotes.org/help/security.
|
||||
p.sk-panel-row.sk-p
|
||||
.info Press Continue to proceed.
|
||||
p
|
||||
.sk-panel-section(ng-if='ctrl.step > 0')
|
||||
.sk-panel-section-title Step {{ctrl.step}} — {{ctrl.titleForStep(ctrl.step)}}
|
||||
div(ng-if='ctrl.step == 1')
|
||||
p.sk-panel-row.sk-p
|
||||
| As a result of this process, the entirety of your data will be
|
||||
| re-encrypted and synced to your account. This is a generally safe
|
||||
| process, but unforeseen factors like poor network connectivity or a
|
||||
| sudden shutdown of your computer may cause this process to fail. It's
|
||||
| best to be on the safe side before large operations such as this one.
|
||||
.sk-panel-row
|
||||
.sk-panel-row
|
||||
.sk-button-group
|
||||
.sk-button.info(ng-click='ctrl.downloadBackup(true)')
|
||||
.sk-label Download Encrypted Backup
|
||||
.sk-button.info(ng-click='ctrl.downloadBackup(false)')
|
||||
.sk-label Download Decrypted Backup
|
||||
div(ng-if='ctrl.step == 2')
|
||||
p.sk-p.sk-panel-row
|
||||
| As a result of this process, your encryption keys will change. Any
|
||||
| device on which you use Standard Notes will need to end its session.
|
||||
| After this process completes, you will be asked to sign back in.
|
||||
p.sk-p.bold.sk-panel-row.info-i
|
||||
| Please sign out of all applications (excluding this one), including:
|
||||
ul
|
||||
li.sk-p Desktop
|
||||
li.sk-p Web (Chrome, Firefox, Safari)
|
||||
li.sk-p Mobile (iOS and Android)
|
||||
p.sk-p.sk-panel-row
|
||||
| If you do not currently have access to a device you're signed in on,
|
||||
| you may proceed, but must make signing out and back in the first step
|
||||
| upon gaining access to that device.
|
||||
p.sk-p.sk-panel-row
|
||||
| Press Continue only when you have
|
||||
| completed signing out of all your devices.
|
||||
div(ng-if='ctrl.step == 3')
|
||||
div(ng-if='ctrl.changePassword')
|
||||
div(ng-if='ctrl.securityUpdate')
|
||||
p.sk-panel-row
|
||||
| Enter your current password. We'll run this through our encryption
|
||||
| scheme to generate strong new encryption keys.
|
||||
.sk-panel-row
|
||||
.sk-panel-row
|
||||
.sk-panel-column.stretch
|
||||
form.sk-panel-form
|
||||
input.sk-input.contrast(
|
||||
ng-model='ctrl.formData.currentPassword',
|
||||
placeholder='Current Password',
|
||||
should-focus='true',
|
||||
sn-autofocus='true',
|
||||
type='password'
|
||||
)
|
||||
input.sk-input.contrast(
|
||||
ng-if='ctrl.changePassword',
|
||||
ng-model='ctrl.formData.newPassword',
|
||||
placeholder='New Password',
|
||||
type='password'
|
||||
)
|
||||
input.sk-input.contrast(
|
||||
ng-if='ctrl.changePassword',
|
||||
ng-model='ctrl.formData.newPasswordConfirmation',
|
||||
placeholder='Confirm New Password',
|
||||
type='password'
|
||||
)
|
||||
div(ng-if='ctrl.step == 4')
|
||||
p.sk-panel-row
|
||||
| Your data is being re-encrypted with your new
|
||||
| keys and synced to your account.
|
||||
p.sk-panel-row.danger(ng-if='ctrl.lockContinue')
|
||||
| Do not close this window until this process completes.
|
||||
.sk-panel-row
|
||||
.sk-panel-column
|
||||
.sk-spinner.small.inline.info.mr-5(ng-if='ctrl.formData.processing')
|
||||
.inline.bold(
|
||||
ng-class="{'info' : !ctrl.formData.statusError, 'error' : ctrl.formData.statusError}"
|
||||
div(ng-if='ctrl.step == 3')
|
||||
.sk-panel-row
|
||||
.sk-panel-column.stretch
|
||||
form.sk-panel-form
|
||||
input.sk-input.contrast(
|
||||
ng-model='ctrl.formData.currentPassword',
|
||||
placeholder='Current Password',
|
||||
should-focus='true',
|
||||
sn-autofocus='true',
|
||||
type='password'
|
||||
)
|
||||
| {{ctrl.formData.status}}
|
||||
.sk-panel-column(
|
||||
delay='1000',
|
||||
delay-hide='true',
|
||||
show='ctrl.syncStatus.syncOpInProgress || ctrl.syncStatus.needsMoreSync'
|
||||
)
|
||||
p.info
|
||||
| Syncing {{ctrl.syncStatus.current}}/{{ctrl.syncStatus.total}}
|
||||
div(ng-if='ctrl.step == 5')
|
||||
div(ng-if='ctrl.changePassword')
|
||||
p.sk-p.sk-panel-row.info-i Your password has been successfully changed.
|
||||
div(ng-if='ctrl.securityUpdate')
|
||||
p.sk-p.sk-panel-row.info-i
|
||||
| The account update has been successfully applied to your account.
|
||||
p.sk-p.sk-panel-row
|
||||
| Please ensure you are running the latest version of Standard Notes
|
||||
| on all platforms to ensure maximum compatibility.
|
||||
p.sk-p.sk-panel-row
|
||||
| You may now sign back in on all your devices and close this window.
|
||||
input.sk-input.contrast(
|
||||
ng-if='ctrl.changePassword',
|
||||
ng-model='ctrl.formData.newPassword',
|
||||
placeholder='New Password',
|
||||
type='password'
|
||||
)
|
||||
input.sk-input.contrast(
|
||||
ng-if='ctrl.changePassword',
|
||||
ng-model='ctrl.formData.newPasswordConfirmation',
|
||||
placeholder='Confirm New Password',
|
||||
type='password'
|
||||
)
|
||||
div(ng-if='ctrl.step == 5')
|
||||
div(ng-if='ctrl.changePassword')
|
||||
p.sk-p.sk-panel-row.info-i Your password has been successfully changed.
|
||||
div(ng-if='ctrl.securityUpdate')
|
||||
p.sk-p.sk-panel-row.info-i
|
||||
| The account update has been successfully applied to your account.
|
||||
p.sk-p.sk-panel-row
|
||||
| Please ensure you are running the latest version of Standard Notes
|
||||
| on all platforms to ensure maximum compatibility.
|
||||
.sk-panel-footer
|
||||
.empty
|
||||
a.sk-a.info.right(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.main-ui-view(
|
||||
ng-class='self.platformString'
|
||||
ng-if='self.state.ready'
|
||||
)
|
||||
lock-screen(
|
||||
ng-if='self.state.needsUnlock'
|
||||
|
||||
279
dist/javascripts/app.js
vendored
279
dist/javascripts/app.js
vendored
File diff suppressed because one or more lines are too long
2
dist/javascripts/app.js.map
vendored
2
dist/javascripts/app.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user