Skip to content

Commit 5eb6559

Browse files
committed
make the master password setup form more informative, #309 [skip ci]
1 parent 73d38d4 commit 5eb6559

13 files changed

+85
-59
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "electron-mail",
33
"description": "Unofficial ProtonMail Desktop App",
4-
"version": "4.8.0",
4+
"version": "4.8.1",
55
"author": "Vladimir Yakovlev <[email protected]>",
66
"license": "MIT",
77
"homepage": "https://github.com/vladimiry/ElectronMail",

src/web/browser-window/app/_notification/notification-item.component.html

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
11
<div
22
[ngClass]="{
3-
'alert-danger': type === 'error' || type === 'errorMessage',
4-
'alert-info': type === 'info',
5-
'alert-secondary': type === 'update'
3+
'alert-danger': item.type === 'error' || (item.type === 'message' && item.data.style === 'error'),
4+
'alert-warning': item.type === 'message' && item.data.style === 'warning',
5+
'alert-info': item.type === 'message' && item.data.style === 'info',
6+
'alert-secondary': item.type === 'update'
67
}"
78
class="alert alert-dismissible"
89
role="alert"
910
>
10-
<ng-container [ngSwitch]="type">
11-
<ng-container *ngSwitchCase="'update'">
12-
<div class="d-inline">
13-
New app version available for download: <span [innerHTML]="message"></span>
14-
<i
15-
[placement]="'bottom'"
16-
[popover]="popTemplate"
17-
class="fa fa-info-circle text-primary align-self-center"
18-
triggers="mouseenter:mouseleave"
19-
></i>
20-
<ng-template #popTemplate>
21-
<p>When you follow the release link scroll down to the "Assets" section to see the installation packages list.</p>
22-
<p class="text-center">
23-
<img alt="Assets list" src="~images/assets-list.gif" style="max-width: 400px;">
24-
</p>
25-
</ng-template>
26-
</div>
11+
<!-- TODO move to "ngSwitch" directive use on https://github.com/angular/angular/issues/20780 resolving -->
12+
<ng-container *ngIf="item.type === 'update'">
13+
<div class="d-inline">
14+
New app version available for download: <span [innerHTML]="message"></span>
15+
<i
16+
[placement]="'bottom'"
17+
[popover]="popTemplate"
18+
class="fa fa-info-circle text-primary align-self-center"
19+
triggers="mouseenter:mouseleave"
20+
></i>
21+
<ng-template #popTemplate>
22+
<p>If you see more than one version on the list it's normally fine to install the newest one.</p>
23+
<p>When you follow the release link scroll down to the "Assets" section to see the installation packages list.</p>
24+
<p class="text-center">
25+
<img alt="Assets list" src="~images/assets-list.gif" style="max-width: 400px;">
26+
</p>
27+
</ng-template>
28+
</div>
29+
</ng-container>
30+
<ng-container *ngIf="item.type === 'error'">
31+
<span [innerText]="message"></span>
32+
</ng-container>
33+
<ng-container *ngIf="item.type === 'message'">
34+
<ng-container [ngSwitch]="item.data.html">
35+
<span *ngSwitchCase="true" [innerHTML]="message"></span>
36+
<span *ngSwitchDefault [innerText]="message"></span>
2737
</ng-container>
28-
<span *ngSwitchDefault [innerText]="message"></span>
2938
</ng-container>
3039
<button (click)="remove()" class="close" type="button">
3140
&times;

src/web/browser-window/app/_notification/notification-item.component.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import {NotificationItem} from "src/web/browser-window/app/store/actions/notific
1111
preserveWhitespaces: true,
1212
})
1313
export class NotificationItemComponent {
14-
type: NotificationItem["type"] = "error";
15-
1614
message = "";
1715

1816
@Output()
@@ -24,12 +22,11 @@ export class NotificationItemComponent {
2422
private _item!: NotificationItem;
2523

2624
@Input()
27-
set item(value: NotificationItem) {
28-
this._item = value;
29-
this.type = value.type;
30-
this.message = value.type === "update"
25+
set item(item: NotificationItem) {
26+
this._item = item;
27+
this.message = item.type === "update"
3128
? (
32-
value.data
29+
item.data
3330
.map(({title, url, date}) => {
3431
const hint = `Published at: ${formatDate(date, "medium", this.locale)}`;
3532
return url
@@ -38,7 +35,11 @@ export class NotificationItemComponent {
3835
})
3936
.join(", ")
4037
)
41-
: value.data.message;
38+
: item.data.message;
39+
}
40+
41+
get item(): NotificationItem {
42+
return this._item;
4243
}
4344

4445
remove(): void {

src/web/browser-window/app/_notification/notification.effects.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ export class NotificationEffects {
1717
() => merge(
1818
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.Error)),
1919
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.ErrorSkipLogging)),
20-
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.ErrorMessage)),
21-
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.Info)),
20+
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.Message)),
2221
this.actions$.pipe(filter(NOTIFICATION_ACTIONS.is.Update)),
2322
).pipe(
2423
map(() => {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const SAVE_PASSWORD_WARN_TRUSTED_HTML = [
2+
`Activating <code>"Keep me signed in"</code> option enables saving the master password in the system's keychain.`,
3+
`In general, storing the password on computer weakens the security but enables automatic login to the app`,
4+
`so you don't have to manually enter the master password each time you start the app.`,
5+
].join(" ");

src/web/browser-window/app/_options/login-base.component.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {filter, map, pairwise} from "rxjs/operators";
77
import {NOTIFICATION_ACTIONS, OPTIONS_ACTIONS} from "src/web/browser-window/app/store/actions";
88
import {ONE_SECOND_MS} from "src/shared/constants";
99
import {OptionsSelectors} from "src/web/browser-window/app/store/selectors";
10+
import {SAVE_PASSWORD_WARN_TRUSTED_HTML} from "./const";
1011
import {State} from "src/web/browser-window/app/store/reducers/options";
1112

1213
@Directive()
@@ -81,9 +82,7 @@ export abstract class LoginBaseComponent implements AfterViewInit, OnDestroy {
8182
filter(([prev, curr]) => curr && Boolean(curr) !== Boolean(prev)),
8283
).subscribe(() => {
8384
this.store.dispatch(
84-
NOTIFICATION_ACTIONS.ErrorMessage({
85-
message: "Saving the master password on computer weakens the security.",
86-
}),
85+
NOTIFICATION_ACTIONS.Message({message: SAVE_PASSWORD_WARN_TRUSTED_HTML, style: "warning", html: true}),
8786
);
8887
}),
8988
);

src/web/browser-window/app/_options/options.effects.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export class OptionsEffects {
4444
this.coreService.logOut();
4545
},
4646
ErrorMessage: ({message}) => {
47-
this.store.dispatch(NOTIFICATION_ACTIONS.ErrorMessage({message}));
47+
this.store.dispatch(NOTIFICATION_ACTIONS.Message({message, style: "error"}));
4848
},
4949
InfoMessage: ({message}) => {
50-
this.store.dispatch(NOTIFICATION_ACTIONS.Info({message}));
50+
this.store.dispatch(NOTIFICATION_ACTIONS.Message({message, style: "info"}));
5151
},
5252
TrayIconDataURL: (payload) => {
5353
this.store.dispatch(OPTIONS_ACTIONS.TrayIconDataURL({value: payload}));

src/web/browser-window/app/_options/save-password-label.component.html

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,21 @@
22
Keep me signed in
33
<i
44
*ngIf="savePassword" [placement]="'bottom'"
5-
[popover]="popTemplate" class="fa fa-info-circle text-danger" container="body" triggers="mouseenter:mouseleave"
5+
[popover]="popTemplate" class="fa fa-info-circle text-warning" container="body" triggers="mouseenter:mouseleave"
66
></i>
7-
<ng-template #popTemplate>
8-
Choosing <code>Keep me signed in</code> option enables saving the master password on your computer. It weakens
9-
the security.
10-
</ng-template>
7+
<ng-template #popTemplate><span [innerHtml]="savePasswordWarnHtmlMessage"></span></ng-template>
118
</ng-container>
129
<ng-template #keytarUnsupportedTemplate>
1310
<code>Keep me signed in</code> feature is unsupported by the system,
14-
<a (click)="toggleKeytarUnsupportedDetails($event)" href>toggle details</a>.
11+
<a (click)="$event.preventDefault(); toggleKeytarUnsupportedDetails()" href>toggle details</a>.
1512
<div [collapse]="!keytarUnsupportedDetails" class="text-left">
1613
<ul>
1714
<li>
1815
First of all please see <a href="https://github.com/vladimiry/ElectronMail/wiki/FAQ">FAQ</a> for more information.
1916
</li>
2017
<li>
21-
See log file in
22-
<a (click)="openSettingsFolder($event)" href>settings folder</a>
23-
for details.
18+
For details, see the <code>log.log</code> file located in the
19+
<a (click)="$event.preventDefault(); openSettingsFolder()" href>settings folder</a>.
2420
</li>
2521
<li *ngIf="snapPasswordManagerServiceHint$ | async">
2622
Try executing <code>sudo snap connect {{ projectName }}:password-manager-service</code>

src/web/browser-window/app/_options/save-password-label.component.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {Subscription} from "rxjs";
55
import {NAVIGATION_ACTIONS} from "src/web/browser-window/app/store/actions";
66
import {OptionsSelectors} from "src/web/browser-window/app/store/selectors";
77
import {PACKAGE_NAME} from "src/shared/constants";
8+
import {SAVE_PASSWORD_WARN_TRUSTED_HTML} from "./const";
89
import {State} from "src/web/browser-window/app/store/reducers/options";
910
import {getZoneNameBoundWebLogger} from "src/web/browser-window/util";
1011

@@ -18,6 +19,8 @@ export class SavePasswordLabelComponent implements OnInit, OnDestroy {
1819

1920
keytarUnsupportedDetails = false;
2021

22+
readonly savePasswordWarnHtmlMessage = SAVE_PASSWORD_WARN_TRUSTED_HTML;
23+
2124
readonly keytarSupport$ = this.store.pipe(
2225
select(OptionsSelectors.FEATURED.keytarSupport),
2326
);
@@ -34,7 +37,7 @@ export class SavePasswordLabelComponent implements OnInit, OnDestroy {
3437

3538
constructor(
3639
private readonly store: Store<State>,
37-
private elementRef: ElementRef,
40+
private readonly elementRef: ElementRef,
3841
) {}
3942

4043
ngOnInit(): void {
@@ -48,13 +51,11 @@ export class SavePasswordLabelComponent implements OnInit, OnDestroy {
4851
});
4952
}
5053

51-
openSettingsFolder(event: Event): void {
52-
event.preventDefault();
54+
openSettingsFolder(): void {
5355
this.store.dispatch(NAVIGATION_ACTIONS.OpenSettingsFolder());
5456
}
5557

56-
toggleKeytarUnsupportedDetails(event: Event): void {
57-
event.preventDefault();
58+
toggleKeytarUnsupportedDetails(): void {
5859
this.keytarUnsupportedDetails = !this.keytarUnsupportedDetails;
5960
}
6061

src/web/browser-window/app/_options/settings-setup.component.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="d-flex justify-content-center">
2-
<form [formGroup]="form" (ngSubmit)="submit()" novalidate>
2+
<form [formGroup]="form" (ngSubmit)="submit()" novalidate class="p-3">
33
<h2>Master Password Setup</h2>
44
<fieldset [disabled]="(signingIn$ | async) || false">
55
<div class="form-row">
@@ -23,6 +23,12 @@ <h2>Master Password Setup</h2>
2323
</div>
2424
</div>
2525
</div>
26+
<div class="form-group text-muted">
27+
The app uses this password to encrypt all the sensitive data to be stored in
28+
the <a (click)="$event.preventDefault(); openSettingsFolder()" href>settings folder</a>.
29+
All the files being produced and stored by the app listed in
30+
the <a (click)="$event.preventDefault(); openFaq()" href>FAQ</a>.
31+
</div>
2632
<button class="btn btn-lg btn-primary btn-block" type="submit" [disabled]="form.invalid">
2733
<i class="fa fa-spinner fa-pulse fa-fw" *ngIf="signingIn$ | async"></i>
2834
Submit

0 commit comments

Comments
 (0)