Skip to content

Commit

Permalink
Added new SSO verified domain call and added calling of it behind fea…
Browse files Browse the repository at this point in the history
…ture flag.
  • Loading branch information
jrmccannon committed Oct 7, 2024
1 parent bf042ef commit adbefd3
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 6 deletions.
26 changes: 20 additions & 6 deletions apps/web/src/app/auth/sso.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import {
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
import { OrganizationDomainSsoDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain-sso-details.response";
import { VerifiedOrganizationDomainSsoDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/verified-organization-domain-sso-details.response";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { HttpStatusCode } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
Expand Down Expand Up @@ -107,13 +110,24 @@ export class SsoComponent extends BaseSsoComponent implements OnInit {
// show loading spinner
this.loggingIn = true;
try {
const response: OrganizationDomainSsoDetailsResponse =
await this.orgDomainApiService.getClaimedOrgDomainByEmail(qParams.email);
if (await this.configService.getFeatureFlag(FeatureFlag.VerifiedSsoDomainEndpoint)) {
const response: ListResponse<VerifiedOrganizationDomainSsoDetailsResponse> =
await this.orgDomainApiService.getVerifiedOrgDomainsByEmail(qParams.email);

if (response?.ssoAvailable && response?.verifiedDate) {
this.identifierFormControl.setValue(response.organizationIdentifier);
await this.submit();
return;
if (response.data.length > 0) {
this.identifierFormControl.setValue(response.data[0].organizationIdentifier);
await this.submit();
return;
}
} else {
const response: OrganizationDomainSsoDetailsResponse =
await this.orgDomainApiService.getClaimedOrgDomainByEmail(qParams.email);

if (response?.ssoAvailable && response?.verifiedDate) {
this.identifierFormControl.setValue(response.organizationIdentifier);
await this.submit();
return;
}
}
} catch (error) {
this.handleGetClaimedDomainByEmailError(error);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ListResponse } from "@bitwarden/common/models/response/list.response";

import { OrganizationDomainRequest } from "../../services/organization-domain/requests/organization-domain.request";

import { OrganizationDomainSsoDetailsResponse } from "./responses/organization-domain-sso-details.response";
import { OrganizationDomainResponse } from "./responses/organization-domain.response";
import { VerifiedOrganizationDomainSsoDetailsResponse } from "./responses/verified-organization-domain-sso-details.response";

export abstract class OrgDomainApiServiceAbstraction {
getAllByOrgId: (orgId: string) => Promise<Array<OrganizationDomainResponse>>;
Expand All @@ -16,4 +19,7 @@ export abstract class OrgDomainApiServiceAbstraction {
verify: (orgId: string, orgDomainId: string) => Promise<OrganizationDomainResponse>;
delete: (orgId: string, orgDomainId: string) => Promise<any>;
getClaimedOrgDomainByEmail: (email: string) => Promise<OrganizationDomainSsoDetailsResponse>;
getVerifiedOrgDomainsByEmail: (
email: string,
) => Promise<ListResponse<VerifiedOrganizationDomainSsoDetailsResponse>>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { BaseResponse } from "@bitwarden/common/models/response/base.response";

export class VerifiedOrganizationDomainSsoDetailsResponse extends BaseResponse {
organizationName: string;
organizationIdentifier: string;
domainName: string;

constructor(response: any) {
super(response);

this.organizationName = this.getResponseProperty("organizationName");
this.organizationIdentifier = this.getResponseProperty("organizationIdentifier");
this.domainName = this.getResponseProperty("domainName");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ const mockedOrganizationDomainSsoDetailsServerResponse = {
verifiedDate: "2022-12-16T21:36:28.68Z",
};

const mockedVerifiedOrganizationDomainSsoDetailsServerResponse = {
organizationIdentifier: "fake-org-identifier",
organizationName: "fake-org",
domainName: "fake-domain-name",
};

const mockedOrganizationDomainSsoDetailsResponse = new OrganizationDomainSsoDetailsResponse(
mockedOrganizationDomainSsoDetailsServerResponse,
);
Expand Down Expand Up @@ -229,4 +235,21 @@ describe("Org Domain API Service", () => {

expect(result).toEqual(mockedOrganizationDomainSsoDetailsResponse);
});

it("getVerifiedOrgDomainsByEmail should call ApiService.send with correct parameters and return response", async () => {
const email = "[email protected]";
apiService.send.mockResolvedValue(mockedVerifiedOrganizationDomainSsoDetailsServerResponse);

const result = await orgDomainApiService.getVerifiedOrgDomainsByEmail(email);

expect(apiService.send).toHaveBeenCalledWith(
"POST",
"/organizations/domain/sso/verified",
new OrganizationDomainSsoDetailsRequest(email),
false, //anonymous
true,
);

expect(result).toEqual(mockedVerifiedOrganizationDomainSsoDetailsServerResponse);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { OrgDomainApiServiceAbstraction } from "../../abstractions/organization-
import { OrgDomainInternalServiceAbstraction } from "../../abstractions/organization-domain/org-domain.service.abstraction";
import { OrganizationDomainSsoDetailsResponse } from "../../abstractions/organization-domain/responses/organization-domain-sso-details.response";
import { OrganizationDomainResponse } from "../../abstractions/organization-domain/responses/organization-domain.response";
import { VerifiedOrganizationDomainSsoDetailsResponse } from "../../abstractions/organization-domain/responses/verified-organization-domain-sso-details.response";

import { OrganizationDomainSsoDetailsRequest } from "./requests/organization-domain-sso-details.request";
import { OrganizationDomainRequest } from "./requests/organization-domain.request";
Expand Down Expand Up @@ -109,4 +110,18 @@ export class OrgDomainApiService implements OrgDomainApiServiceAbstraction {

return response;
}

async getVerifiedOrgDomainsByEmail(
email: string,
): Promise<ListResponse<VerifiedOrganizationDomainSsoDetailsResponse>> {
const result = await this.apiService.send(
"POST",
`/organizations/domain/sso/verified`,
new OrganizationDomainSsoDetailsRequest(email),
false, // anonymous
true,
);

return new ListResponse(result, VerifiedOrganizationDomainSsoDetailsResponse);
}
}
2 changes: 2 additions & 0 deletions libs/common/src/enums/feature-flag.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export enum FeatureFlag {
CipherKeyEncryption = "cipher-key-encryption",
PM11901_RefactorSelfHostingLicenseUploader = "PM-11901-refactor-self-hosting-license-uploader",
Pm3478RefactorOrganizationUserApi = "pm-3478-refactor-organizationuser-api",
VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint",
}

export type AllowedFeatureFlagTypes = boolean | number | string;
Expand Down Expand Up @@ -76,6 +77,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.CipherKeyEncryption]: FALSE,
[FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader]: FALSE,
[FeatureFlag.Pm3478RefactorOrganizationUserApi]: FALSE,
[FeatureFlag.VerifiedSsoDomainEndpoint]: FALSE,
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;

export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;
Expand Down

0 comments on commit adbefd3

Please sign in to comment.