1
0
mirror of https://github.com/bitwarden/web synced 2025-12-06 00:03:28 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Kyle Spearrin
ab42320b23 auth request for passwordless login 2022-01-13 13:12:47 -05:00
Vince Grassia
3292d119fe Update Version Bump action (#1388) 2022-01-12 16:06:50 -05:00
Christian Oliff
b8de92435b Add Inputmode for tel and email (identities) (#1384) 2022-01-12 10:07:56 +01:00
6 changed files with 87 additions and 8 deletions

View File

@@ -27,13 +27,13 @@ jobs:
ref: version_bump_${{ github.event.inputs.version_number }} ref: version_bump_${{ github.event.inputs.version_number }}
- name: Bump Version - package.json - name: Bump Version - package.json
uses: bitwarden/gh-actions/version-bump@0c263b3963211ccaf5804313c3b3a0bcc52d4b19 uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with: with:
version: ${{ github.event.inputs.version_number }} version: ${{ github.event.inputs.version_number }}
file_path: "./package.json" file_path: "./package.json"
- name: Bump Version - package-lock.json - name: Bump Version - package-lock.json
uses: bitwarden/gh-actions/version-bump@0c263b3963211ccaf5804313c3b3a0bcc52d4b19 uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with: with:
version: ${{ github.event.inputs.version_number }} version: ${{ github.event.inputs.version_number }}
file_path: "./package-lock.json" file_path: "./package-lock.json"

2
jslib

Submodule jslib updated: e4cd0af2f9...27a37dc34b

View File

@@ -89,6 +89,20 @@
<i class="fa fa-pencil-square-o" aria-hidden="true"></i> {{ "createAccount" | i18n }} <i class="fa fa-pencil-square-o" aria-hidden="true"></i> {{ "createAccount" | i18n }}
</a> </a>
</div> </div>
<div class="d-flex">
<button
type="button"
(click)="startPasswordlessLogin()"
class="btn btn-outline-secondary btn-block btn-submit mt-2"
>
<span> <i class="fa fa-key" aria-hidden="true"></i> Passwordless</span>
<i
class="fa fa-spinner fa-spin"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
</button>
</div>
<div class="d-flex"> <div class="d-flex">
<a routerLink="/sso" class="btn btn-outline-secondary btn-block mt-2"> <a routerLink="/sso" class="btn btn-outline-secondary btn-block mt-2">
<i class="fa fa-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }} <i class="fa fa-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }}

View File

@@ -4,11 +4,15 @@ import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs/operators"; import { first } from "rxjs/operators";
import { ApiService } from "jslib-common/abstractions/api.service"; import { ApiService } from "jslib-common/abstractions/api.service";
import { AppIdService } from "jslib-common/abstractions/appId.service";
import { AuthService } from "jslib-common/abstractions/auth.service"; import { AuthService } from "jslib-common/abstractions/auth.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CryptoFunctionService } from "jslib-common/abstractions/cryptoFunction.service"; import { CryptoFunctionService } from "jslib-common/abstractions/cryptoFunction.service";
import { CryptoService } from "jslib-common/abstractions/crypto.service";
import { EnvironmentService } from "jslib-common/abstractions/environment.service"; import { EnvironmentService } from "jslib-common/abstractions/environment.service";
import { I18nService } from "jslib-common/abstractions/i18n.service"; import { I18nService } from "jslib-common/abstractions/i18n.service";
import { LogService } from "jslib-common/abstractions/log.service"; import { LogService } from "jslib-common/abstractions/log.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service"; import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service"; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { PolicyService } from "jslib-common/abstractions/policy.service"; import { PolicyService } from "jslib-common/abstractions/policy.service";
@@ -35,10 +39,14 @@ export class LoginComponent extends BaseLoginComponent {
environmentService: EnvironmentService, environmentService: EnvironmentService,
passwordGenerationService: PasswordGenerationService, passwordGenerationService: PasswordGenerationService,
cryptoFunctionService: CryptoFunctionService, cryptoFunctionService: CryptoFunctionService,
private apiService: ApiService, apiService: ApiService,
private policyService: PolicyService, private policyService: PolicyService,
logService: LogService, logService: LogService,
ngZone: NgZone ngZone: NgZone,
appIdService: AppIdService,
broadcasterService: BroadcasterService,
cryptoService: CryptoService,
messagingService: MessagingService
) { ) {
super( super(
authService, authService,
@@ -50,7 +58,12 @@ export class LoginComponent extends BaseLoginComponent {
passwordGenerationService, passwordGenerationService,
cryptoFunctionService, cryptoFunctionService,
logService, logService,
ngZone ngZone,
apiService,
appIdService,
broadcasterService,
cryptoService,
messagingService
); );
this.onSuccessfulLoginNavigate = this.goAfterLogIn; this.onSuccessfulLoginNavigate = this.goAfterLogIn;
} }

View File

@@ -3,8 +3,9 @@ import { DomSanitizer } from "@angular/platform-browser";
import { NavigationEnd, Router } from "@angular/router"; import { NavigationEnd, Router } from "@angular/router";
import * as jq from "jquery"; import * as jq from "jquery";
import { IndividualConfig, ToastrService } from "ngx-toastr"; import { IndividualConfig, ToastrService } from "ngx-toastr";
import Swal from "sweetalert2"; import Swal, { SweetAlertIcon } from "sweetalert2";
import { ApiService } from "jslib-common/abstractions/api.service";
import { AuthService } from "jslib-common/abstractions/auth.service"; import { AuthService } from "jslib-common/abstractions/auth.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service"; import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CipherService } from "jslib-common/abstractions/cipher.service"; import { CipherService } from "jslib-common/abstractions/cipher.service";
@@ -39,6 +40,10 @@ import { SendOptionsPolicy } from "./organizations/policies/send-options.compone
import { SingleOrgPolicy } from "./organizations/policies/single-org.component"; import { SingleOrgPolicy } from "./organizations/policies/single-org.component";
import { TwoFactorAuthenticationPolicy } from "./organizations/policies/two-factor-authentication.component"; import { TwoFactorAuthenticationPolicy } from "./organizations/policies/two-factor-authentication.component";
import { Utils } from "jslib-common/misc/utils";
import { AuthRequestUpdateRequest } from "jslib-common/models/request/authRequestUpdateRequest";
import { AppIdService } from "jslib-common/abstractions/appId.service";
const BroadcasterSubscriptionId = "AppComponent"; const BroadcasterSubscriptionId = "AppComponent";
const IdleTimeout = 60000 * 10; // 10 minutes const IdleTimeout = 60000 * 10; // 10 minutes
@@ -76,7 +81,9 @@ export class AppComponent implements OnDestroy, OnInit {
private eventService: EventService, private eventService: EventService,
private policyService: PolicyService, private policyService: PolicyService,
protected policyListService: PolicyListService, protected policyListService: PolicyListService,
private keyConnectorService: KeyConnectorService private keyConnectorService: KeyConnectorService,
private apiService: ApiService,
private appIdService: AppIdService
) {} ) {}
ngOnInit() { ngOnInit() {
@@ -167,6 +174,49 @@ export class AppComponent implements OnDestroy, OnInit {
this.keyConnectorService.setConvertAccountRequired(true); this.keyConnectorService.setConvertAccountRequired(true);
this.router.navigate(["/remove-password"]); this.router.navigate(["/remove-password"]);
break; break;
case "closeDialog":
Swal.close();
break;
case "authRequest":
Swal.close();
const authRequestId = message.id;
console.log("Got request for " + authRequestId);
const authRequest = await this.apiService.getAuthRequest(authRequestId);
const email = await this.stateService.getEmail();
const requestPublicKey = Utils.fromB64ToArray(authRequest.publicKey).buffer;
const fingerprint = await this.cryptoService.getFingerprint(email, requestPublicKey);
const authRequestConfirmed = await this.platformUtilsService.showDialog(
`Another device is requesting to log into your Bitwarden account. Do you want to allow it?<br /><br />
<b><u>Details</u></b><br />
Device: Opera Browser<br />
IP Address: ${authRequest.requestIpAddress}<br />
Time: ${authRequest.creationDate}<br /><br />
<b><u>Public Key Fingerprint</u></b><br />
<code>${fingerprint.join("-")}</code>`,
"New Login Request",
"Yes, Allow",
"No, Deny",
null,
true
);
if (authRequestConfirmed) {
const masterKey = await this.cryptoService.getKey();
const masterKeyHash = await this.cryptoService.getKeyHash();
const encMasterKey = await this.cryptoService.rsaEncrypt(
masterKey.key,
requestPublicKey
);
const encMasterKeyHash = await this.cryptoService.rsaEncrypt(
Utils.fromB64ToArray(masterKeyHash).buffer,
requestPublicKey
);
const authRequestUpdate = new AuthRequestUpdateRequest();
authRequestUpdate.deviceIdentifier = await this.appIdService.getAppId();
authRequestUpdate.key = encMasterKey.encryptedString;
authRequestUpdate.masterPasswordHash = encMasterKeyHash.encryptedString;
this.apiService.putAuthRequest(authRequest.id, authRequestUpdate);
}
break;
default: default:
break; break;
} }

View File

@@ -587,6 +587,7 @@
id="idEmail" id="idEmail"
class="form-control" class="form-control"
type="text" type="text"
inputmode="email"
name="Identity.Email" name="Identity.Email"
[(ngModel)]="cipher.identity.email" [(ngModel)]="cipher.identity.email"
appInputVerbatim appInputVerbatim
@@ -599,6 +600,7 @@
id="idPhone" id="idPhone"
class="form-control" class="form-control"
type="text" type="text"
inputmode="tel"
name="Identity.Phone" name="Identity.Phone"
[(ngModel)]="cipher.identity.phone" [(ngModel)]="cipher.identity.phone"
[disabled]="cipher.isDeleted || viewOnly" [disabled]="cipher.isDeleted || viewOnly"