Add owner email to provider org creation (#1101)
* Add owner email to provider org creation * Use Correct request model * Update jslib * Remove unused input * Remove unused input * Improve client owner email description
This commit is contained in:
parent
8ebefb9a2e
commit
f6df9983a3
2
jslib
2
jslib
|
@ -1 +1 @@
|
||||||
Subproject commit 23309d33e2a335574ed898d6543040372d41526a
|
Subproject commit fdf0eb989be49e6f5d8215f2eac1da275923f427
|
|
@ -8,7 +8,8 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="file">{{'licenseFile' | i18n}}</label>
|
<label for="file">{{'licenseFile' | i18n}}</label>
|
||||||
<input type="file" id="file" class="form-control-file" name="file" required>
|
<input type="file" id="file" class="form-control-file" name="file" required>
|
||||||
<small class="form-text text-muted">{{'licenseFileDesc' | i18n : 'bitwarden_organization_license.json'}}</small>
|
<small class="form-text text-muted">{{'licenseFileDesc' | i18n :
|
||||||
|
'bitwarden_organization_license.json'}}</small>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
||||||
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
||||||
|
@ -34,22 +35,19 @@
|
||||||
<input id="email" class="form-control" type="text" name="Email" [(ngModel)]="clientOwnerEmail" required>
|
<input id="email" class="form-control" type="text" name="Email" [(ngModel)]="clientOwnerEmail" required>
|
||||||
<small class="text-muted">{{'ownerDesc' | i18n : '20'}}</small>
|
<small class="text-muted">{{'ownerDesc' | i18n : '20'}}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-6" *ngIf="!!providerId">
|
</div>
|
||||||
<label for="businessName">{{'businessName' | i18n}}</label>
|
<div *ngIf="!providerId">
|
||||||
<input id="businessName" class="form-control" type="text" name="BusinessName" [(ngModel)]="businessName">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!providerId">
|
|
||||||
<div class="form-group form-check">
|
<div class="form-group form-check">
|
||||||
<input id="ownedBusiness" class="form-check-input" type="checkbox" name="OwnedBusiness" [(ngModel)]="ownedBusiness"
|
<input id="ownedBusiness" class="form-check-input" type="checkbox" name="OwnedBusiness"
|
||||||
(change)="changedOwnedBusiness()">
|
[(ngModel)]="ownedBusiness" (change)="changedOwnedBusiness()">
|
||||||
<label for="ownedBusiness" class="form-check-label">{{'accountOwnedBusiness' | i18n}}</label>
|
<label for="ownedBusiness" class="form-check-label">{{'accountOwnedBusiness' | i18n}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" *ngIf="ownedBusiness">
|
<div class="row" *ngIf="ownedBusiness">
|
||||||
<div class="form-group col-6">
|
<div class="form-group col-6">
|
||||||
<label for="businessName">{{'businessName' | i18n}}</label>
|
<label for="businessName">{{'businessName' | i18n}}</label>
|
||||||
<input id="businessName" class="form-control" type="text" name="BusinessName" [(ngModel)]="businessName">
|
<input id="businessName" class="form-control" type="text" name="BusinessName"
|
||||||
</div>
|
[(ngModel)]="businessName">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mt-5">{{'chooseYourPlan' | i18n}}</h2>
|
<h2 class="mt-5">{{'chooseYourPlan' | i18n}}</h2>
|
||||||
|
@ -99,7 +97,7 @@
|
||||||
{{'includesXUsers' | i18n : selectableProduct.baseSeats}}
|
{{'includesXUsers' | i18n : selectableProduct.baseSeats}}
|
||||||
<ng-container *ngIf="selectableProduct.hasAdditionalSeatsOption">
|
<ng-container *ngIf="selectableProduct.hasAdditionalSeatsOption">
|
||||||
{{('additionalUsers' | i18n).toLowerCase()}}
|
{{('additionalUsers' | i18n).toLowerCase()}}
|
||||||
{{selectableProduct.seatPrice / 12 | currency:'$'}} /{{'month' | i18n}}
|
{{selectableProduct.seatPrice / 12 | currency:'$'}} /{{'month' | i18n}}
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</span>
|
</span>
|
||||||
|
@ -128,8 +126,8 @@
|
||||||
<label for="additionalSeats">{{'additionalUserSeats' | i18n}}</label>
|
<label for="additionalSeats">{{'additionalUserSeats' | i18n}}</label>
|
||||||
<input id="additionalSeats" class="form-control" type="number" name="AdditionalSeats"
|
<input id="additionalSeats" class="form-control" type="number" name="AdditionalSeats"
|
||||||
[(ngModel)]="additionalSeats" min="0" max="100000" placeholder="{{'userSeatsDesc' | i18n}}">
|
[(ngModel)]="additionalSeats" min="0" max="100000" placeholder="{{'userSeatsDesc' | i18n}}">
|
||||||
<small
|
<small class="text-muted form-text">{{'userSeatsAdditionalDesc' | i18n : selectedPlan.baseSeats :
|
||||||
class="text-muted form-text">{{'userSeatsAdditionalDesc' | i18n : selectedPlan.baseSeats : (seatPriceMonthly(selectedPlan) | currency:'$')}}</small>
|
(seatPriceMonthly(selectedPlan) | currency:'$')}}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -138,8 +136,8 @@
|
||||||
<input id="additionalStorage" class="form-control" type="number" name="AdditionalStorageGb"
|
<input id="additionalStorage" class="form-control" type="number" name="AdditionalStorageGb"
|
||||||
[(ngModel)]="additionalStorage" min="0" max="99" step="1"
|
[(ngModel)]="additionalStorage" min="0" max="99" step="1"
|
||||||
placeholder="{{'additionalStorageGbDesc' | i18n}}">
|
placeholder="{{'additionalStorageGbDesc' | i18n}}">
|
||||||
<small
|
<small class="text-muted form-text">{{'additionalStorageIntervalDesc' | i18n : '1 GB' :
|
||||||
class="text-muted form-text">{{'additionalStorageIntervalDesc' | i18n : '1 GB' : (additionalStoragePriceMonthly(selectedPlan) | currency:'$') : ('month' | i18n)}}</small>
|
(additionalStoragePriceMonthly(selectedPlan) | currency:'$') : ('month' | i18n)}}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -149,8 +147,8 @@
|
||||||
[(ngModel)]="premiumAccessAddon">
|
[(ngModel)]="premiumAccessAddon">
|
||||||
<label for="premiumAccess" class="form-check-label bold">{{'premiumAccess' | i18n}}</label>
|
<label for="premiumAccess" class="form-check-label bold">{{'premiumAccess' | i18n}}</label>
|
||||||
</div>
|
</div>
|
||||||
<small
|
<small class="text-muted form-text">{{'premiumAccessDesc' | i18n : (3.33 | currency:'$') : ('month' |
|
||||||
class="text-muted form-text">{{'premiumAccessDesc' | i18n : (3.33 | currency:'$') : ('month' | i18n)}}</small>
|
i18n)}}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="spaced-header">{{'summary' | i18n}}</h2>
|
<h2 class="spaced-header">{{'summary' | i18n}}</h2>
|
||||||
|
@ -172,7 +170,7 @@
|
||||||
<span *ngIf="!selectablePlan.baseSeats">{{'users' | i18n}}:</span>
|
<span *ngIf="!selectablePlan.baseSeats">{{'users' | i18n}}:</span>
|
||||||
{{additionalSeats || 0}} × {{selectablePlan.seatPrice / 12 | currency:'$'}} × 12
|
{{additionalSeats || 0}} × {{selectablePlan.seatPrice / 12 | currency:'$'}} × 12
|
||||||
{{'monthAbbr' | i18n}} = {{seatTotal(selectablePlan)
|
{{'monthAbbr' | i18n}} = {{seatTotal(selectablePlan)
|
||||||
| currency:'$'}} /{{'year' | i18n}}
|
| currency:'$'}} /{{'year' | i18n}}
|
||||||
</small>
|
</small>
|
||||||
<small *ngIf="selectablePlan.hasAdditionalStorageOption">
|
<small *ngIf="selectablePlan.hasAdditionalStorageOption">
|
||||||
{{'additionalStorageGb' | i18n}}: {{additionalStorage || 0}} ×
|
{{'additionalStorageGb' | i18n}}: {{additionalStorage || 0}} ×
|
||||||
|
@ -201,7 +199,7 @@
|
||||||
<span *ngIf="!selectablePlan.baseSeats">{{'users' | i18n}}:</span>
|
<span *ngIf="!selectablePlan.baseSeats">{{'users' | i18n}}:</span>
|
||||||
{{additionalSeats || 0}} × {{selectablePlan.seatPrice | currency:'$'}}
|
{{additionalSeats || 0}} × {{selectablePlan.seatPrice | currency:'$'}}
|
||||||
{{'monthAbbr' | i18n}} = {{seatTotal(selectablePlan)
|
{{'monthAbbr' | i18n}} = {{seatTotal(selectablePlan)
|
||||||
| currency:'$'}} /{{'month' | i18n}}
|
| currency:'$'}} /{{'month' | i18n}}
|
||||||
</small>
|
</small>
|
||||||
<small *ngIf="selectablePlan.hasAdditionalStorageOption">
|
<small *ngIf="selectablePlan.hasAdditionalStorageOption">
|
||||||
{{'additionalStorageGb' | i18n}}: {{additionalStorage || 0}} ×
|
{{'additionalStorageGb' | i18n}}: {{additionalStorage || 0}} ×
|
||||||
|
@ -219,7 +217,8 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<hr class="my-3">
|
<hr class="my-3">
|
||||||
<h2 class="spaced-header mb-4">{{ (createOrganization ? 'paymentInformation' : 'billingInformation') | i18n}}</h2>
|
<h2 class="spaced-header mb-4">{{ (createOrganization ? 'paymentInformation' : 'billingInformation') | i18n}}
|
||||||
|
</h2>
|
||||||
<app-payment *ngIf="createOrganization" [hideCredit]="true"></app-payment>
|
<app-payment *ngIf="createOrganization" [hideCredit]="true"></app-payment>
|
||||||
<app-tax-info (onCountryChanged)="changedCountry()"></app-tax-info>
|
<app-tax-info (onCountryChanged)="changedCountry()"></app-tax-info>
|
||||||
<div id="price" class="my-4">
|
<div id="price" class="my-4">
|
||||||
|
@ -237,7 +236,7 @@
|
||||||
<small class="text-muted font-italic" *ngIf="freeTrial && createOrganization; else paymentChargedImmediately">
|
<small class="text-muted font-italic" *ngIf="freeTrial && createOrganization; else paymentChargedImmediately">
|
||||||
{{'paymentChargedWithTrial' | i18n : (selectedPlanInterval | i18n) }}
|
{{'paymentChargedWithTrial' | i18n : (selectedPlanInterval | i18n) }}
|
||||||
</small>
|
</small>
|
||||||
<ng-template #paymentChargedImmediately>
|
<ng-template #paymentChargedImmediately>
|
||||||
<small class="text-muted font-italic mt-2 d-block">
|
<small class="text-muted font-italic mt-2 d-block">
|
||||||
{{'paymentCharged' | i18n : (selectedPlanInterval | i18n) }}
|
{{'paymentCharged' | i18n : (selectedPlanInterval | i18n) }}
|
||||||
</small>
|
</small>
|
||||||
|
|
|
@ -34,6 +34,7 @@ import { ProductType } from 'jslib-common/enums/productType';
|
||||||
import { OrganizationCreateRequest } from 'jslib-common/models/request/organizationCreateRequest';
|
import { OrganizationCreateRequest } from 'jslib-common/models/request/organizationCreateRequest';
|
||||||
import { OrganizationKeysRequest } from 'jslib-common/models/request/organizationKeysRequest';
|
import { OrganizationKeysRequest } from 'jslib-common/models/request/organizationKeysRequest';
|
||||||
import { OrganizationUpgradeRequest } from 'jslib-common/models/request/organizationUpgradeRequest';
|
import { OrganizationUpgradeRequest } from 'jslib-common/models/request/organizationUpgradeRequest';
|
||||||
|
import { ProviderOrganizationCreateRequest } from 'jslib-common/models/request/provider/providerOrganizationCreateRequest';
|
||||||
|
|
||||||
import { PlanResponse } from 'jslib-common/models/response/planResponse';
|
import { PlanResponse } from 'jslib-common/models/response/planResponse';
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ export class OrganizationPlansComponent implements OnInit {
|
||||||
additionalSeats: number = 0;
|
additionalSeats: number = 0;
|
||||||
name: string;
|
name: string;
|
||||||
billingEmail: string;
|
billingEmail: string;
|
||||||
|
clientOwnerEmail: string;
|
||||||
businessName: string;
|
businessName: string;
|
||||||
productTypes = ProductType;
|
productTypes = ProductType;
|
||||||
formPromise: Promise<any>;
|
formPromise: Promise<any>;
|
||||||
|
@ -336,9 +338,12 @@ export class OrganizationPlansComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.providerId) {
|
if (this.providerId) {
|
||||||
|
const providerRequest = new ProviderOrganizationCreateRequest(this.clientOwnerEmail, request);
|
||||||
const providerKey = await this.cryptoService.getProviderKey(this.providerId);
|
const providerKey = await this.cryptoService.getProviderKey(this.providerId);
|
||||||
request.key = (await this.cryptoService.encrypt(orgKey.key, providerKey)).encryptedString;
|
providerRequest.organizationCreateRequest.key = (await this.cryptoService.encrypt(orgKey.key, providerKey)).encryptedString;
|
||||||
return (await this.apiService.postProviderCreateOrganization(this.providerId, request)).id;
|
const orgId = (await this.apiService.postProviderCreateOrganization(this.providerId, providerRequest)).organizationId;
|
||||||
|
|
||||||
|
return orgId;
|
||||||
} else {
|
} else {
|
||||||
return (await this.apiService.postOrganization(request)).id;
|
return (await this.apiService.postOrganization(request)).id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2238,12 +2238,18 @@
|
||||||
"confirmed": {
|
"confirmed": {
|
||||||
"message": "Confirmed"
|
"message": "Confirmed"
|
||||||
},
|
},
|
||||||
|
"clientOwnerEmail": {
|
||||||
|
"message": "Client Owner Email"
|
||||||
|
},
|
||||||
"owner": {
|
"owner": {
|
||||||
"message": "Owner"
|
"message": "Owner"
|
||||||
},
|
},
|
||||||
"ownerDesc": {
|
"ownerDesc": {
|
||||||
"message": "The highest access user that can manage all aspects of your organization."
|
"message": "The highest access user that can manage all aspects of your organization."
|
||||||
},
|
},
|
||||||
|
"clientOwnerDesc": {
|
||||||
|
"message": "This email should NOT be associated with the provider. This user will have permissions to access and manage all aspects of this organization."
|
||||||
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"message": "Admin"
|
"message": "Admin"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue