1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

SG-680 - (1) Created Org Domain API and observable based data store service (2) Created required response and request models

This commit is contained in:
Jared Snider
2022-11-29 18:28:08 -05:00
parent 1af4b5cbda
commit 6f20cc24e1
6 changed files with 205 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
import { OrganizationDomainResponse } from "../../models/response/organization-domain.response";
export class OrgDomainApiServiceAbstraction {
getByOrgId: (orgId: string) => Promise<OrganizationDomainResponse>;
getByOrgIdAndOrgDomainId: (
orgId: string,
orgDomainId: string
) => Promise<OrganizationDomainResponse>;
post: (orgId: string, orgDomain: OrganizationDomainResponse) => Promise<any>;
verify: (orgId: string, orgDomainId: string) => Promise<boolean>;
delete: (orgId: string, orgDomainId: string) => Promise<any>;
}

View File

@@ -0,0 +1,18 @@
import { Observable } from "rxjs";
import { OrganizationDomainResponse } from "../../models/response/organization-domain.response";
export abstract class OrgDomainReadServiceAbstraction {
orgDomains$: Observable<OrganizationDomainResponse[]>;
get: (orgDomainId: string) => Promise<OrganizationDomainResponse>;
}
// Note: this separate class is designed to hold methods that are not
// meant to be used in components (e.g., data write methods)
export abstract class OrgDomainFullServiceAbstraction extends OrgDomainReadServiceAbstraction {
upsert: (orgDomains: OrganizationDomainResponse[]) => void;
replace: (orgDomains: OrganizationDomainResponse[]) => void;
clearCache: () => Promise<void>;
delete: (orgDomainIds: string[]) => void;
}

View File

@@ -0,0 +1,11 @@
import { OrganizationDomainResponse } from "../response/organization-domain.response";
export class OrganizationDomainRequest {
txt: string;
domainName: string;
constructor(orgDomainResponse: OrganizationDomainResponse) {
this.txt = orgDomainResponse.txt;
this.domainName = orgDomainResponse.domainName;
}
}

View File

@@ -0,0 +1,29 @@
import { BaseResponse } from "./base.response";
export class OrganizationDomainResponse extends BaseResponse {
id: string;
organizationId: string;
txt: string;
domainName: string;
creationDate: string;
nextRunDate: string;
jobRunCount: number;
verifiedDate?: string;
constructor(response: any) {
super(response);
this.id = this.getResponseProperty("Id");
this.organizationId = this.getResponseProperty("OrganizationId");
this.txt = this.getResponseProperty("Txt");
this.domainName = this.getResponseProperty("DomainName");
this.creationDate = this.getResponseProperty("CreationDate");
this.nextRunDate = this.getResponseProperty("NextRunDate");
this.jobRunCount = this.getResponseProperty("JobRunCount");
this.verifiedDate = this.getResponseProperty("VerifiedDate");
// Might be worth converting string dates to actual dates for ease of use
// this.creationDate = obj.creationDate != null ? new Date(obj.creationDate) : null;
// this.nextRunDate = obj.nextRunDate != null ? new Date(obj.nextRunDate) : null;
// this.verifiedDate = obj.verifiedDate != null ? new Date(obj.verifiedDate) : null;
}
}

View File

@@ -0,0 +1,69 @@
import { OrgDomainApiServiceAbstraction } from "../../abstractions/organization-domain/org-domain-api.service.abstraction";
import { OrganizationDomainRequest } from "../../models/request/organization-domain.request";
import { OrganizationDomainResponse } from "../../models/response/organization-domain.response";
import { ApiService } from "../api.service";
import { OrgDomainService } from "./org-domain.service";
export class OrgDomainApiService implements OrgDomainApiServiceAbstraction {
constructor(private orgDomainService: OrgDomainService, private apiService: ApiService) {}
async getByOrgId(orgId: string): Promise<OrganizationDomainResponse> {
const result = await this.apiService.send(
"GET",
`/organizations/${orgId}/domain`,
null,
true,
true
);
return new OrganizationDomainResponse(result);
}
async getByOrgIdAndOrgDomainId(
orgId: string,
orgDomainId: string
): Promise<OrganizationDomainResponse> {
const result = await this.apiService.send(
"GET",
`/organizations/${orgId}/domain/${orgDomainId}`,
null,
true,
true
);
return new OrganizationDomainResponse(result);
}
async post(orgId: string, orgDomain: OrganizationDomainResponse): Promise<any> {
const request = new OrganizationDomainRequest(orgDomain);
const result = await this.apiService.send(
"POST",
`/organizations/${orgId}`,
request,
true,
true
);
const response = new OrganizationDomainResponse(result);
await this.orgDomainService.upsert([response]);
return response;
}
async verify(orgId: string, orgDomainId: string): Promise<boolean> {
const result: boolean = await this.apiService.send(
"POST",
`/organizations/${orgId}/${orgDomainId}/verify`,
null,
true,
true
);
return result;
}
async delete(orgId: string, orgDomainId: string): Promise<any> {
this.apiService.send("DELETE", `/organizations/${orgId}/${orgDomainId}`, null, true, false);
await this.orgDomainService.delete([orgDomainId]);
}
}

View File

@@ -0,0 +1,66 @@
import { BehaviorSubject } from "rxjs";
import { OrgDomainFullServiceAbstraction } from "../../abstractions/organization-domain/org-domain.service.abstraction";
import { OrganizationDomainResponse } from "../../models/response/organization-domain.response";
export class OrgDomainService implements OrgDomainFullServiceAbstraction {
protected _orgDomains$: BehaviorSubject<OrganizationDomainResponse[]> = new BehaviorSubject([]);
orgDomains$ = this._orgDomains$.asObservable();
// eslint-disable-next-line @typescript-eslint/no-empty-function
constructor() {}
async get(orgDomainId: string): Promise<OrganizationDomainResponse> {
const orgDomains: OrganizationDomainResponse[] = this._orgDomains$.getValue();
return orgDomains.find((orgDomain) => orgDomain.id === orgDomainId);
}
upsert(orgDomains: OrganizationDomainResponse[]): void {
const existingOrgDomains: OrganizationDomainResponse[] = this._orgDomains$.getValue();
orgDomains.forEach((orgDomain: OrganizationDomainResponse) => {
// Determine if passed in orgDomain exists in existing array:
const index = existingOrgDomains.findIndex(
(existingOrgDomain) => existingOrgDomain.id === orgDomain.id
);
if (index !== -1) {
// existing
existingOrgDomains[index] = orgDomain;
} else {
// new item
existingOrgDomains.push(orgDomain);
}
});
this._orgDomains$.next(existingOrgDomains);
}
replace(orgDomains: OrganizationDomainResponse[]): void {
this._orgDomains$.next(orgDomains);
}
async clearCache(): Promise<void> {
this._orgDomains$.next([]);
}
delete(orgDomainIds: string[]): void {
const existingOrgDomains: OrganizationDomainResponse[] = this._orgDomains$.getValue();
orgDomainIds.forEach((orgDomainId: string) => {
const index = existingOrgDomains.findIndex(
(existingOrgDomain) => existingOrgDomain.id === orgDomainId
);
if (index !== -1) {
// existing
delete existingOrgDomains[index];
} else {
// eslint-disable-next-line no-console
console.warn(`Unable to delete OrgDomainId: ${orgDomainId}`);
}
});
this._orgDomains$.next(existingOrgDomains);
}
}