Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-3812][PM-3809] Unify Create and Login Passkeys UI #6403

Merged
Show file tree
Hide file tree
Changes from 98 commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
124ba75
PM-1235 Added component to display passkey on auth flow
LRNcardozoWDF Aug 29, 2023
3adb863
PM-1235 Implement basic structure and behaviour of UI
LRNcardozoWDF Aug 31, 2023
dac8706
PM-1235 Added localised strings
LRNcardozoWDF Aug 31, 2023
7db1cf4
PM-1235 Improved button UI
LRNcardozoWDF Aug 31, 2023
70c0169
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
LRNcardozoWDF Sep 1, 2023
30d7bbb
Implemented view passkey button
gbubemismith Sep 4, 2023
aaafac0
Implemented multiple matching passkeys
gbubemismith Sep 5, 2023
e39a106
Refactored fido2 popup to use browser popout windows service
gbubemismith Sep 7, 2023
84c8173
[PM-3807] feat: remove non-discoverable from fido2 user interface class
coroiu Sep 8, 2023
119fe9b
[PM-3807] feat: merge fido2 component ui
coroiu Sep 8, 2023
7effcd4
[PM-3807] feat: return `cipherId` from user interface
coroiu Sep 8, 2023
d074b9a
[PM-3807] feat: merge credential creation logic in authenticator
coroiu Sep 8, 2023
0cf7641
[PM-3807] feat: merge credential assertion logic in authenticator
coroiu Sep 8, 2023
03b3bf5
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Sep 8, 2023
474cbfd
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Sep 8, 2023
ea3d00e
merged with feature branch and fixed conflicts
gbubemismith Sep 9, 2023
b7472d4
updated test cases and services using the config service
gbubemismith Sep 9, 2023
28e669d
[PM-3807] feat: add `discoverable` property to fido2keys
coroiu Sep 7, 2023
c8bae9c
[PM-3807] feat: assign discoverable property during creation
coroiu Sep 7, 2023
6cee3b8
[PM-3807] feat: save discoverable field to server
coroiu Sep 11, 2023
84c43be
[PM-3807] feat: filter credentials by rpId AND discoverable
coroiu Sep 11, 2023
85a3903
[PM-3807] chore: remove discoverable tests which are no longer needed
coroiu Sep 11, 2023
afae855
[PM-3807] chore: remove all logic for handling standalone Fido2Key
coroiu Sep 11, 2023
a6d4db9
[PM-3807] fix: add missing discoverable property handling to tests
coroiu Sep 11, 2023
e54277b
merged with Andreas branch for testing
gbubemismith Sep 11, 2023
e9b7cd7
merged with feature branch and fixed conflicts
gbubemismith Sep 13, 2023
eb1f7ee
updated locales with new text
gbubemismith Sep 15, 2023
4c73595
Updated popout windows service to use defined type for custom width a…
gbubemismith Sep 15, 2023
824e1dd
Update on unifying auth flow ui to align with architecture changes
gbubemismith Sep 15, 2023
cdb6e09
Moved click event
gbubemismith Sep 15, 2023
1e1bb71
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Sep 16, 2023
278f700
Throw dom exception error if tab is null
gbubemismith Sep 17, 2023
5d2c350
updated fido2key object to array
gbubemismith Sep 17, 2023
6639daa
removed discoverable key in client inerface service for now
gbubemismith Sep 17, 2023
73c4fe2
Get senderTabId from the query params and send to the view cipher com…
gbubemismith Sep 17, 2023
84b3f91
Refactored view item if passkeys exists and the cipher row views by h…
gbubemismith Sep 17, 2023
1dff160
Allow fido2 pop out close wehn cancle is clicked on add edit component
gbubemismith Sep 18, 2023
28021be
Removed makshift run in angular zone
gbubemismith Sep 18, 2023
a33e456
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Sep 18, 2023
5de3f52
created focus directive to target first element in ngFor for displaye…
Jingo88 Sep 18, 2023
d3f0caa
Refactored to use switch statement and added condtional on search and…
gbubemismith Sep 19, 2023
da283fb
Adjusted footer link and added more features to the login flow
gbubemismith Sep 19, 2023
d83c323
Added host listener to abort when window is closed
gbubemismith Sep 19, 2023
7c4c4c5
remove custom focus directive. instead stuck focus logic into fido2-c…
Jingo88 Sep 19, 2023
ce3919a
Fixed bug where close and cancel on view and add component does not a…
gbubemismith Sep 19, 2023
4a949e4
show info dialog when user account does not have master password
gbubemismith Sep 20, 2023
d6ba70d
Removed PopupUtilsService
gbubemismith Sep 20, 2023
c26c78f
show info dialog when user account does not have master password
gbubemismith Sep 20, 2023
8aa3c40
Added comments
gbubemismith Sep 20, 2023
feef3c7
Added comments
gbubemismith Sep 20, 2023
06cefc8
made row height consistent
gbubemismith Sep 20, 2023
62f59de
update logo to be dynamic with theme selection
Jingo88 Sep 20, 2023
88184fe
added new translation key
gbubemismith Sep 20, 2023
0002d9c
Merge branch 'PM-3812/unify-ui-create-passkeys' of github.com:bitward…
gbubemismith Sep 20, 2023
4bd369e
Dis some styling to align cipher items
gbubemismith Sep 21, 2023
bd84909
Changed passkey icon fill color
gbubemismith Sep 21, 2023
0da670d
updated flow of focus and selected items in the passkey popup
Jingo88 Sep 21, 2023
e84b0c6
Fixed merge conflicts
gbubemismith Sep 22, 2023
2a4ad41
Fixed bug when picking a credential
gbubemismith Sep 22, 2023
5a63e7b
Added text to lock popout screen
gbubemismith Sep 22, 2023
acdff84
Added passkeys test to home view
gbubemismith Sep 22, 2023
1a6135d
changed class name
gbubemismith Sep 22, 2023
fd54e23
Added uilocation as a query paramter to know if the user is in the po…
gbubemismith Sep 24, 2023
ca048ab
update fido2 component for dynamic subtitleText as well as additional…
Jingo88 Sep 25, 2023
fcbceb7
moved another method out of html
Jingo88 Sep 25, 2023
9914a65
Added window id return to single action popout and used the window id…
gbubemismith Sep 25, 2023
70f9ebe
Merge branch 'PM-1245' into PM-3812/unify-ui-create-passkeys
gbubemismith Sep 25, 2023
46dda36
Merge branch 'PM-4025' into PM-3812/unify-ui-create-passkeys
gbubemismith Sep 25, 2023
f38dd37
removed duplicate activatedroute
gbubemismith Sep 25, 2023
6d79ab7
added a doNotSaveUrl true to 2fa options, so the previousUrl can rema…
gbubemismith Sep 25, 2023
4b7396e
Added a div to restrict the use browser link ot the buttom left
gbubemismith Sep 25, 2023
d77da99
reverted view change which is handled by the view pr
gbubemismith Sep 26, 2023
cad3820
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Sep 26, 2023
ee87665
merged and fixed conflicts
gbubemismith Sep 27, 2023
91f7cca
Updated locales text and removed unused variable
gbubemismith Sep 27, 2023
55e3b19
Fixed issue where new cipher is not created for non discoverable keys
gbubemismith Sep 28, 2023
a0ef46b
switched from using svg for the logo to CL
gbubemismith Sep 29, 2023
fa6c7a0
removed svg files
gbubemismith Sep 29, 2023
7e07274
default to browser implmentation if user is logged out of the browser…
gbubemismith Sep 29, 2023
2f5a03a
removed passkeys knowledge from login, 2fa
gbubemismith Sep 29, 2023
eba1584
Added fido2 use browser link component and a state service to reduce …
gbubemismith Oct 1, 2023
3e1800c
removed function and removed unnecessary comment
gbubemismith Oct 2, 2023
1d1585a
reverted to former
gbubemismith Oct 2, 2023
b2d322b
merged and fixed conflicts
gbubemismith Oct 2, 2023
d9b4b65
[PM-4148] Added descriptive error messages (#6475)
gbubemismith Oct 3, 2023
384db12
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Oct 3, 2023
c1dfb52
Merge branch 'EC-598-beeep-properly-store-passkeys-in-bitwarden' into…
gbubemismith Oct 5, 2023
d76a3fc
replaced fido2 state service with higher order inject functions
gbubemismith Oct 5, 2023
e579f17
removed null check for tab
gbubemismith Oct 5, 2023
b8edd62
refactor fido2 cipher row component
Jingo88 Oct 5, 2023
2668fbe
added a static abort function to the browser interface service
gbubemismith Oct 6, 2023
cc0ee6c
Merge branch 'PM-3812/unify-ui-create-passkeys' of github.com:bitward…
gbubemismith Oct 6, 2023
9754fb0
removed width from content
gbubemismith Oct 6, 2023
7d4308f
uncommented code
gbubemismith Oct 6, 2023
feae5ea
removed sessionId from query params and redudant styles
gbubemismith Oct 6, 2023
a507999
Put back removed sessionId
gbubemismith Oct 9, 2023
580095e
Added fallbackRequested parameter to abortPopout and added comments t…
gbubemismith Oct 9, 2023
3913952
minor styling update to fix padding and color on selected ciphers
Jingo88 Oct 9, 2023
2380833
update padding again to address vertical pushdown of cipher selection
Jingo88 Oct 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 65 additions & 11 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2419,6 +2419,21 @@
"message": "Toggle collapse",
"description": "Toggling an expand/collapse state."
},
"aliasDomain": {
"message": "Alias domain"
},
"passwordRepromptDisabledAutofillOnPageLoad": {
"message": "Items with master password re-prompt cannot be auto-filled on page load. Auto-fill on page load turned off.",
"description": "Toast message for describing that master password re-prompt cannot be auto-filled on page load."
},
"autofillOnPageLoadSetToDefault": {
"message": "Auto-fill on page load set to use default setting.",
"description": "Toast message for informing the user that auto-fill on page load has been set to the default setting."
},
"turnOffMasterPasswordPromptToEditField": {
"message": "Turn off master password re-prompt to edit this field",
"description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item."
},
"loginPasskey": {
"message": "This login uses a passkey"
},
Expand All @@ -2434,19 +2449,58 @@
"passkeyNotCopiedAlert": {
"message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?"
},
"aliasDomain": {
"message": "Alias domain"
"passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": {
"message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password."
},
"passwordRepromptDisabledAutofillOnPageLoad": {
"message": "Items with master password re-prompt cannot be auto-filled on page load. Auto-fill on page load turned off.",
"description": "Toast message for describing that master password re-prompt cannot be auto-filled on page load."
"logInWithPasskey": {
"message": "Log in with passkey?"
},
"autofillOnPageLoadSetToDefault": {
"message": "Auto-fill on page load set to use default setting.",
"description": "Toast message for informing the user that auto-fill on page load has been set to the default setting."
"savePasskeyInBitwarden": {
"message": "Save passkey in Bitwarden?"
},
"turnOffMasterPasswordPromptToEditField": {
"message": "Turn off master password re-prompt to edit this field",
"description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item."
"passkeyAlreadyExists": {
"message": "A passkey already exists for this application."
},
"noPasskeysFoundForThisApplication": {
"message": "No passkeys found for this application."
},
"noMatchingPasskeyLogin": {
"message": "You do not have a matching login for this site."
},
"confirm": {
"message": "Confirm"
},
"savePasskey": {
"message": "Save passkey"
},
"savePasskeyNewLogin": {
"message": "Save passkey as new login"
},
"choosePasskey": {
"message": "Choose a login to save this passkey to"
},
"fido2Item": {
"message": "Fido2 Item"
},
"overwritePasskey": {
"message": "Overwrite passkey?"
},
"overwritePasskeyAlert": {
"message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?"
},
"featureNotSupported": {
"message": "Feature not yet supported"
},
"searchLogins": {
"message": "Search all logins"
},
"yourPasskeyIsLocked": {
"message": "Authentication required to use passkey. Verify your identity to continue."
},
"loginToSavePasskey": {
"message": "Log in to use passkeys in Bitwarden"
},
"useBrowserName": {
"message": "Use browser"
}
}
5 changes: 0 additions & 5 deletions apps/browser/src/auth/guards/fido2-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ export const fido2AuthGuard: CanActivateFn = async (

const authStatus = await authService.getAuthStatus();

if (authStatus === AuthenticationStatus.LoggedOut) {
routerService.setPreviousUrl(state.url);
return router.createUrlTree(["/home"], { queryParams: route.queryParams });
}

if (authStatus === AuthenticationStatus.Locked) {
routerService.setPreviousUrl(state.url);
return router.createUrlTree(["/lock"], { queryParams: route.queryParams });
Expand Down
154 changes: 82 additions & 72 deletions apps/browser/src/auth/popup/lock.component.html
Hinton marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -11,81 +11,91 @@ <h1 class="center">
</div>
</header>
<main tabindex="-1">
<div class="box">
<div class="box-content">
<div
class="box-content-row box-content-row-flex"
appBoxRow
*ngIf="pinEnabled || masterPasswordEnabled"
>
<div class="row-main" *ngIf="pinEnabled">
<label for="pin">{{ "pin" | i18n }}</label>
<input
id="pin"
type="{{ showPassword ? 'text' : 'password' }}"
name="PIN"
class="monospaced"
[(ngModel)]="pin"
required
appInputVerbatim
/>
</div>
<div class="row-main" *ngIf="masterPasswordEnabled && !pinEnabled">
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
aria-describedby="masterPasswordHelp"
class="monospaced"
[(ngModel)]="masterPassword"
required
appInputVerbatim
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
(click)="togglePassword()"
[attr.aria-pressed]="showPassword"
>
<i
class="bwi bwi-lg"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
aria-hidden="true"
></i>
</button>
<ng-container *ngIf="fido2PopoutSessionData$ | async as fido2Data">
<div class="box">
<div class="box-content">
<div
class="box-content-row box-content-row-flex"
appBoxRow
*ngIf="pinEnabled || masterPasswordEnabled"
>
<div class="row-main" *ngIf="pinEnabled">
<label for="pin">{{ "pin" | i18n }}</label>
<input
id="pin"
type="{{ showPassword ? 'text' : 'password' }}"
name="PIN"
class="monospaced"
[(ngModel)]="pin"
required
appInputVerbatim
/>
</div>
<div class="row-main" *ngIf="masterPasswordEnabled && !pinEnabled">
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
aria-describedby="masterPasswordHelp"
class="monospaced"
[(ngModel)]="masterPassword"
required
appInputVerbatim
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
(click)="togglePassword()"
[attr.aria-pressed]="showPassword"
>
<i
class="bwi bwi-lg"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
aria-hidden="true"
></i>
</button>
</div>
</div>
</div>
<div id="masterPasswordHelp" class="box-footer">
<p>
{{
fido2Data.isFido2Session
? ("yourPasskeyIsLocked" | i18n)
: ("yourVaultIsLocked" | i18n)
}}
</p>
{{ "loggedInAsOn" | i18n : email : webVaultHostname }}
</div>
</div>
<div id="masterPasswordHelp" class="box-footer">
<p>{{ "yourVaultIsLocked" | i18n }}</p>
{{ "loggedInAsOn" | i18n : email : webVaultHostname }}
</div>
</div>
<div class="box" *ngIf="biometricLock">
<div class="box-footer no-pad">
<button
type="button"
class="btn primary block"
(click)="unlockBiometric()"
appStopClick
[disabled]="pendingBiometric"
>
{{ "unlockWithBiometrics" | i18n }}
</button>
<div class="box" *ngIf="biometricLock">
<div class="box-footer no-pad">
<button
type="button"
class="btn primary block"
(click)="unlockBiometric()"
appStopClick
[disabled]="pendingBiometric"
>
{{ "unlockWithBiometrics" | i18n }}
</button>
</div>
</div>
</div>
<p class="text-center">
<button type="button" appStopClick (click)="logOut()">{{ "logOut" | i18n }}</button>
</p>
<app-private-mode-warning></app-private-mode-warning>
<app-callout *ngIf="biometricError" type="error">{{ biometricError }}</app-callout>
<p class="text-center text-muted" *ngIf="pendingBiometric">
<i class="bwi bwi-spinner bwi-spin" aria-hidden="true"></i> {{ "awaitDesktop" | i18n }}
</p>
<p class="text-center" *ngIf="!fido2Data.isFido2Session">
<button type="button" appStopClick (click)="logOut()">{{ "logOut" | i18n }}</button>
</p>
<app-private-mode-warning></app-private-mode-warning>
<app-callout *ngIf="biometricError" type="error">{{ biometricError }}</app-callout>
<p class="text-center text-muted" *ngIf="pendingBiometric">
<i class="bwi bwi-spinner bwi-spin" aria-hidden="true"></i> {{ "awaitDesktop" | i18n }}
</p>

<app-fido2-use-browser-link></app-fido2-use-browser-link>
</ng-container>
</main>
</form>
2 changes: 2 additions & 0 deletions apps/browser/src/auth/popup/lock.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { DialogService } from "@bitwarden/components";

import { BiometricErrors, BiometricErrorTypes } from "../../models/biometricErrors";
import { BrowserRouterService } from "../../platform/popup/services/browser-router.service";
import { fido2PopoutSessionData$ } from "../../vault/fido2/browser-fido2-user-interface.service";

@Component({
selector: "app-lock",
Expand All @@ -33,6 +34,7 @@ export class LockComponent extends BaseLockComponent {

biometricError: string;
pendingBiometric = false;
fido2PopoutSessionData$ = fido2PopoutSessionData$();

constructor(
router: Router,
Expand Down
6 changes: 4 additions & 2 deletions apps/browser/src/background/main.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,9 @@ export default class MainBackground {

this.browserPopoutWindowService = new BrowserPopoutWindowService();

this.popupUtilsService = new PopupUtilsService(this.isPrivateMode);
this.fido2UserInterfaceService = new BrowserFido2UserInterfaceService(this.popupUtilsService);
this.fido2UserInterfaceService = new BrowserFido2UserInterfaceService(
this.browserPopoutWindowService
);
this.fido2AuthenticatorService = new Fido2AuthenticatorService(
this.cipherService,
this.fido2UserInterfaceService,
Expand All @@ -571,6 +572,7 @@ export default class MainBackground {
this.fido2ClientService = new Fido2ClientService(
this.fido2AuthenticatorService,
this.configService,
this.authService,
this.logService
);

Expand Down
4 changes: 2 additions & 2 deletions apps/browser/src/background/runtime.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,11 @@ export default class RuntimeBackground {
return await this.main.fido2ClientService.isFido2FeatureEnabled();
case "fido2RegisterCredentialRequest":
return await this.abortManager.runWithAbortController(msg.requestId, (abortController) =>
this.main.fido2ClientService.createCredential(msg.data, abortController)
this.main.fido2ClientService.createCredential(msg.data, sender.tab, abortController)
);
case "fido2GetCredentialRequest":
return await this.abortManager.runWithAbortController(msg.requestId, (abortController) =>
this.main.fido2ClientService.assertCredential(msg.data, abortController)
this.main.fido2ClientService.assertCredential(msg.data, sender.tab, abortController)
);
}
}
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will all change with #6296. Please ensure that PR is merged before this lands in master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cagonzalezcs had talked with @gbubemismith and preferred for Passkeys to land in master prior to his PR. I'd like to make sure we are on the same page as to the order here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have preferred the other way around since #6296 seems ready to merge while passkeys in vault have a few bugs and things to fix first. But either works.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ interface BrowserPopoutWindowService {
}
): Promise<void>;
closePasswordRepromptPrompt(): Promise<void>;
openFido2Popout(
senderWindowId: number,
promptData: {
sessionId: string;
senderTabId: number;
fallbackSupported: boolean;
}
): Promise<number>;
closeFido2Popout(): Promise<void>;
}

export { BrowserPopoutWindowService };
Loading
Loading