mirror of
https://github.com/bitwarden/server.git
synced 2025-05-08 05:02:21 -05:00

* [NO LOGIC] Rename MultiOrganizationEnterprise to BusinessUnit * [Core] Add IMailService.SendBusinessUnitConversionInviteAsync * [Core] Add BusinessUnitConverter * [Admin] Add new permission * [Admin] Add BusinessUnitConverterController * [Admin] Add Convert to Business Unit button to Organization edit page * [Api] Add OrganizationBillingController.SetupBusinessUnitAsync action * [Multi] Propagate provider type to sync response * [Multi] Put updates behind feature flag * [Tests] BusinessUnitConverterTests * Run dotnet format * Fixing post-main merge compilation failure
162 lines
7.4 KiB
Plaintext
162 lines
7.4 KiB
Plaintext
@using Bit.Admin.Enums;
|
|
@using Bit.Admin.Models
|
|
@using Bit.Core
|
|
@using Bit.Core.AdminConsole.Enums.Provider
|
|
@using Bit.Core.Billing.Enums
|
|
@using Bit.Core.Billing.Extensions
|
|
@using Bit.Core.Services
|
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
|
@inject Bit.Admin.Services.IAccessControlService AccessControlService
|
|
@inject IFeatureService FeatureService
|
|
@model OrganizationEditModel
|
|
@{
|
|
ViewData["Title"] = (Model.Provider != null ? "Client " : string.Empty) + "Organization: " + Model.Name;
|
|
|
|
var canViewOrganizationInformation = AccessControlService.UserHasPermission(Permission.Org_OrgInformation_View);
|
|
var canViewBillingInformation = AccessControlService.UserHasPermission(Permission.Org_BillingInformation_View);
|
|
var canInitiateTrial = AccessControlService.UserHasPermission(Permission.Org_InitiateTrial);
|
|
var canRequestDelete = AccessControlService.UserHasPermission(Permission.Org_RequestDelete);
|
|
var canDelete = AccessControlService.UserHasPermission(Permission.Org_Delete);
|
|
var canUnlinkFromProvider = AccessControlService.UserHasPermission(Permission.Provider_Edit);
|
|
|
|
var canConvertToBusinessUnit =
|
|
FeatureService.IsEnabled(FeatureFlagKeys.PM18770_EnableOrganizationBusinessUnitConversion) &&
|
|
AccessControlService.UserHasPermission(Permission.Org_Billing_ConvertToBusinessUnit) &&
|
|
Model.Organization.PlanType.GetProductTier() == ProductTierType.Enterprise &&
|
|
!string.IsNullOrEmpty(Model.Organization.GatewaySubscriptionId) &&
|
|
Model.Provider is null or { Type: ProviderType.BusinessUnit, Status: ProviderStatusType.Pending };
|
|
}
|
|
|
|
@section Scripts {
|
|
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationFormScripts.cshtml")
|
|
|
|
<script>
|
|
(() => {
|
|
const treamsTrialButton = document.getElementById('teams-trial');
|
|
if (treamsTrialButton != null) {
|
|
treamsTrialButton.addEventListener('click', () => {
|
|
if (document.getElementById('@(nameof(Model.PlanType))').value !== '@((byte)PlanType.Free)') {
|
|
alert('Organization is not on a free plan.');
|
|
return;
|
|
}
|
|
setTrialDefaults('@((byte)PlanType.TeamsAnnually)');
|
|
togglePlanFeatures('@((byte)PlanType.TeamsAnnually)');
|
|
document.getElementById('@(nameof(Model.Plan))').value = 'Teams (Trial)';
|
|
});
|
|
}
|
|
|
|
const entTrialButton = document.getElementById('enterprise-trial');
|
|
if (entTrialButton != null) {
|
|
entTrialButton.addEventListener('click', () => {
|
|
if (document.getElementById('@(nameof(Model.PlanType))').value !== '@((byte)PlanType.Free)') {
|
|
alert('Organization is not on a free plan.');
|
|
return;
|
|
}
|
|
setTrialDefaults('@((byte)PlanType.EnterpriseAnnually)');
|
|
togglePlanFeatures('@((byte)PlanType.EnterpriseAnnually)');
|
|
document.getElementById('@(nameof(Model.Plan))').value = 'Enterprise (Trial)';
|
|
});
|
|
}
|
|
|
|
const initDeleteButton = document.getElementById('initiate-delete-form');
|
|
if (initDeleteButton != null) {
|
|
initDeleteButton.addEventListener('submit', (e) => {
|
|
const email = prompt('Enter the email address of the owner/admin that your want to ' +
|
|
'request the organization delete verification process with.');
|
|
document.getElementById('AdminEmail').value = email;
|
|
if (email == null || email === '') {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
}
|
|
|
|
function setTrialDefaults(planType) {
|
|
// Plan
|
|
document.getElementById('@(nameof(Model.PlanType))').value = planType;
|
|
// Password Manager
|
|
document.getElementById('@(nameof(Model.Seats))').value = '10';
|
|
document.getElementById('@(nameof(Model.MaxCollections))').value = '';
|
|
document.getElementById('@(nameof(Model.MaxStorageGb))').value = '1';
|
|
// Secret Manager
|
|
if (document.getElementById('@(nameof(Model.UseSecretsManager))').checked) {
|
|
document.getElementById('@(nameof(Model.SmSeats))').value = '10';
|
|
document.getElementById('@(nameof(Model.SmServiceAccounts))').value = getPlan(planType)?.baseServiceAccount;
|
|
}
|
|
// Licensing
|
|
document.getElementById('@(nameof(Model.LicenseKey))').value = '@Model.RandomLicenseKey';
|
|
document.getElementById('@(nameof(Model.ExpirationDate))').value = '@Model.FourteenDayExpirationDate';
|
|
document.getElementById('@(nameof(Model.SalesAssistedTrialStarted))').value = true;
|
|
}
|
|
})();
|
|
</script>
|
|
}
|
|
|
|
<h1>@(Model.Provider != null ? "Client " : string.Empty)Organization <small>@Model.Name</small></h1>
|
|
|
|
@if (Model.Provider != null)
|
|
{
|
|
<h2>Provider Relationship</h2>
|
|
@await Html.PartialAsync("_ProviderInformation", Model.Provider)
|
|
}
|
|
|
|
@if (canViewOrganizationInformation)
|
|
{
|
|
<h2>Organization Information</h2>
|
|
@await Html.PartialAsync("_ViewInformation", Model)
|
|
}
|
|
|
|
@if (canViewBillingInformation)
|
|
{
|
|
<h2>Billing Information</h2>
|
|
@await Html.PartialAsync("_BillingInformation",
|
|
new BillingInformationModel { BillingInfo = Model.BillingInfo, BillingHistoryInfo = Model.BillingHistoryInfo, OrganizationId = Model.Organization.Id, Entity = "Organization" })
|
|
}
|
|
|
|
@await Html.PartialAsync("~/AdminConsole/Views/Shared/_OrganizationForm.cshtml", Model)
|
|
|
|
<div class="d-flex mt-4">
|
|
<button type="submit" class="btn btn-primary" form="edit-form">Save</button>
|
|
<div class="ms-auto d-flex">
|
|
@if (canInitiateTrial && Model.Provider is null)
|
|
{
|
|
<button class="btn btn-secondary me-2" type="button" id="teams-trial">
|
|
Teams Trial
|
|
</button>
|
|
<button class="btn btn-secondary me-2" type="button" id="enterprise-trial">
|
|
Enterprise Trial
|
|
</button>
|
|
}
|
|
@if (canConvertToBusinessUnit)
|
|
{
|
|
<a asp-controller="BusinessUnitConversion"
|
|
asp-action="Index"
|
|
asp-route-organizationId="@Model.Organization.Id"
|
|
class="btn btn-secondary me-2">
|
|
Convert to Business Unit
|
|
</a>
|
|
}
|
|
@if (canUnlinkFromProvider && Model.Provider is not null)
|
|
{
|
|
<button class="btn btn-outline-danger me-2"
|
|
onclick="return unlinkProvider('@Model.Organization.Id');">
|
|
Unlink provider
|
|
</button>
|
|
}
|
|
@if (canRequestDelete)
|
|
{
|
|
<form asp-action="DeleteInitiation" asp-route-id="@Model.Organization.Id" id="initiate-delete-form">
|
|
<input type="hidden" name="AdminEmail" id="AdminEmail" />
|
|
<button class="btn btn-danger me-2" type="submit">Request Delete</button>
|
|
</form>
|
|
}
|
|
@if (canDelete)
|
|
{
|
|
<form asp-action="Delete" asp-route-id="@Model.Organization.Id"
|
|
onsubmit="return confirm('Are you sure you want to hard delete this organization?')">
|
|
<button class="btn btn-outline-danger" type="submit">Delete</button>
|
|
</form>
|
|
}
|
|
</div>
|
|
</div>
|
|
|