bitwarden-estensione-browser/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access.service.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

129 lines
4.5 KiB
TypeScript
Raw Normal View History

SM-310 [] Secrets (#3355) * [SM-63] Secrets List overview (#3239) The purpose of this PR is to create a new component for the Secrets Manager project where all the secrets associated to a specific organization ID can be viewed. * [SM-63] Secrets List overview (#3239) The purpose of this PR is to create a new component for the Secrets Manager project where all the secrets associated to a specific organization ID can be viewed. * [SM-63] Display dates based off Figma (#3358) * Display dates based off Figma * Swapping date to medium format * [SM-185] Use feature flags for secrets (#3409) * Fix SM lint errors (#3526) * Fix SM lint errors * Update bitwarden_license/bit-web/src/app/sm/secrets/secrets.component.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * [SM-65] Create/Edit Secrets Dialog (#3376) The purpose of this PR is to add a Create/Edit Secrets dialog component. * [SM-198] Empty Secrets View (#3585) * SM-198 Empty Secrets View * [SM-64] Soft delete secrets (#3549) * Soft delete secrets * SM-95-ProjectList (#3508) * Adding project list and creating a shared module for secrets * updates to style , temporarily using secrets results until API portion is completed * removing non project related options from the list, updting api call to call projects now * Adding view project option from drop down * Changes requested by Thomas * Changes requested by Thomas * suggested fixes * fixes after merge from master * Adding decrypting to project list * Update bitwarden_license/bit-web/src/app/sm/shared/sm-shared.module.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Update bitwarden_license/bit-web/src/app/sm/projects/project.service.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Update bitwarden_license/bit-web/src/app/sm/projects/project.service.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * fix to projectRequest so name is type EncString instead of string * lint + prettier fixes * Oscar's suggestions - Removing this. from projectList * updating to use bitIconButton * Updating to use BitIconButton Co-authored-by: CarleyDiaz-Bitwarden <103955722+CarleyDiaz-Bitwarden@users.noreply.github.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Fix double edit secret dialog (#3645) * Fix typescript errors on secrets init (#3649) * Resolve breaking changes * Remove unecessary class * SM-198 Update empty list text. (#3652) * [SM-267] Minor visual fixes (#3673) * SM-96: Add/Edit Project for SM (#3616) * SM-96: Initial add for Add/Edit project * Update secrets.module.ts * Small fixes based on PR comments * SM-96: Small fixes + fix new project creation * Fully fix create / edit project * SM-96: Update toast text * Remove message with exclamation * SM-96: Fix broken build * SM-96: Remove disabled on save buttons for SM dialogs & switch to early exits * SM-96: Run linter * [SM-186] Service Accounts - Overview (#3653) * SM-186 Service Accounts Overview * Remove duplicate titles (#3659) * [SM-187] Create Service Account Dialog (#3710) * SM-187 Create Service Account Dialog * Fix renamed paths * SM Modal Updates (#3776) * Add type=button to cancel button on sm dialogs * Update new secret/project modal titles to match design * Add loading spinner for project and secret edit modals * Add max length to project name * Use Tailwind CSS class instead of custom and remove click handler * Fix spinner * Add buttonType=primary to project dialog save button * Fix loading change for secret dialog and use tw-text-center Co-authored-by: Hinton <hinton@users.noreply.github.com> * [SM-113] Delete Projects Dialog (#3777) * SM-113 Add Delete Projects Dialog * [SM-306] Migrate secrets dialog to async form (#3849) * [SM-310] Prepare secrets manager for merge to master (#3885) * Remove Built In Validator on Project Delete (#3909) Handle all Project Delete validation through custom validator * [SM-312] Mark all inputs as touched when submitting (#3920) * Use new icon for no item (#3917) * Create navigation component (#3881) * [SM-150] Project / Secret mapping (#3912) * wip * removing added file * updates * handling projects and secrets mapping in UI * moving files and fixing errors * Update bitwarden_license/bit-web/src/app/secrets-manager/secrets/secrets-list.component.html Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * Decrypt the name * fixing the secrets-list.component bug * renaming file and view name * lint fixes * removing secret with projects list response, and other misc name changes * Adding back things I shouldnt have deleted * Update bitwarden_license/bit-web/src/app/secrets-manager/secrets/responses/secret-with-projects-list.response.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * updating button (#3779) * [SM-300] Access Tokens (#3955) * [SM-301] fix: associate labels with inputs (#4058) * fix: wrap input in label * fix: update all label in projects and service accounts * [SM-196] Create Access Token Dialog (#4095) * Add create access token dialog * Use ServiceAccountView for access token creation * Set version to readonly for access token * DRY up Expiration Date & bug fix * Break out expiration options component * Move expiration-options to layout; Match FIGMA * Create Generic Key generator * Add getByServiceAccountId * Change to use keyMaterial and not the full key * Use access token id, not service account * Remove generic key generator * Swap to service account name placeholder * Swap ExpirationOptions to a CVA * No longer masking according to FIGMA * Remove schema comment * Code review updates * Update required logic and approach * Move ExpirationOptionsComponent into access Co-authored-by: Hinton <hinton@users.noreply.github.com> * SM-99: Individual Project / Secrets Tab (#4011) Co-authored-by: Hinton <hinton@users.noreply.github.com> * Fixes for the demo (#4159) * [SM-360] Add support for never expiring access tokens (#4150) * Add support for never expiring access tokens * Render performance fixes * Update bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/dialogs/expiration-options.component.ts Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * [SM-360] Fix access token display dialog for never expiring tokens (#4164) * Fix access token display dialog * Add disableClose to access token display dialog * [SM-299] Add license checks (#4078) * [SM-69] feature: create org-switcher, bit-nav-item, bit-nav-group, bit-nav-divider (#4073) * feat: create nav-item, nav-group, org-switcher * add tree variant; add stories; move to component library * render button if no link is present * fix routerLinkActive; add template comments; fix styles * update storybook stories * rename to route * a11y fixes * update stories * simplify tree nesting * rename nav-base component * add divider; finish org-switcher; add overview page skeleton * add nav-divider story * code review * rename components to CL naming scheme * fix iconButton focus color * apply code review changes * fix strict template route param * add ariaLabel input; update org-switcher a11y * add two way binding for nav-group open state; update stories * add toggle control to org-switcher * [SM-310] Disable Secrets Manager in QA (#4199) Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Thomas Avery <tavery@bitwarden.com> Co-authored-by: CarleyDiaz-Bitwarden <103955722+CarleyDiaz-Bitwarden@users.noreply.github.com> Co-authored-by: cd-bitwarden <106776772+cd-bitwarden@users.noreply.github.com> Co-authored-by: Colton Hurst <colton@coltonhurst.com> Co-authored-by: Will Martin <contact@willmartian.com>
2022-12-09 11:21:07 +01:00
import { Injectable } from "@angular/core";
import { Subject } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service";
import { EncryptService } from "@bitwarden/common/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/misc/utils";
import { EncString } from "@bitwarden/common/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/models/domain/symmetric-crypto-key";
import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { AccessTokenRequest } from "../models/requests/access-token.request";
import { AccessTokenCreationResponse } from "../models/responses/access-token-creation.response";
import { AccessTokenResponse } from "../models/responses/access-tokens.response";
import { AccessTokenView } from "../models/view/access-token.view";
@Injectable({
providedIn: "root",
})
export class AccessService {
private readonly _accessTokenVersion = "0";
protected _accessToken: Subject<AccessTokenView> = new Subject();
accessToken$ = this._accessToken.asObservable();
constructor(
private cryptoService: CryptoService,
private apiService: ApiService,
private cryptoFunctionService: CryptoFunctionService,
private encryptService: EncryptService
) {}
async getAccessTokens(
organizationId: string,
serviceAccountId: string
): Promise<AccessTokenView[]> {
const r = await this.apiService.send(
"GET",
"/service-accounts/" + serviceAccountId + "/access-tokens",
null,
true,
true
);
const results = new ListResponse(r, AccessTokenResponse);
return await this.createAccessTokenViews(organizationId, results.data);
}
async createAccessToken(
organizationId: string,
serviceAccountId: string,
accessTokenView: AccessTokenView
): Promise<string> {
const keyMaterial = await this.cryptoFunctionService.randomBytes(16);
const key = await this.cryptoFunctionService.hkdf(
keyMaterial,
"bitwarden-accesstoken",
"sm-access-token",
64,
"sha256"
);
const encryptionKey = new SymmetricCryptoKey(key);
const request = await this.createAccessTokenRequest(
organizationId,
encryptionKey,
accessTokenView
);
const r = await this.apiService.send(
"POST",
"/service-accounts/" + serviceAccountId + "/access-tokens",
request,
true,
true
);
const result = new AccessTokenCreationResponse(r);
this._accessToken.next(null);
const b64Key = Utils.fromBufferToB64(keyMaterial);
return `${this._accessTokenVersion}.${result.id}.${result.clientSecret}:${b64Key}`;
}
private async createAccessTokenRequest(
organizationId: string,
encryptionKey: SymmetricCryptoKey,
accessTokenView: AccessTokenView
): Promise<AccessTokenRequest> {
const organizationKey = await this.getOrganizationKey(organizationId);
const accessTokenRequest = new AccessTokenRequest();
const [name, encryptedPayload, key] = await Promise.all([
await this.encryptService.encrypt(accessTokenView.name, organizationKey),
await this.encryptService.encrypt(
JSON.stringify({ encryptionKey: organizationKey.keyB64 }),
encryptionKey
),
await this.encryptService.encrypt(encryptionKey.keyB64, organizationKey),
]);
accessTokenRequest.name = name;
accessTokenRequest.encryptedPayload = encryptedPayload;
accessTokenRequest.key = key;
accessTokenRequest.expireAt = accessTokenView.expireAt;
return accessTokenRequest;
}
private async getOrganizationKey(organizationId: string): Promise<SymmetricCryptoKey> {
return await this.cryptoService.getOrgKey(organizationId);
}
private async createAccessTokenViews(
organizationId: string,
accessTokenResponses: AccessTokenResponse[]
): Promise<AccessTokenView[]> {
const orgKey = await this.getOrganizationKey(organizationId);
return await Promise.all(
accessTokenResponses.map(async (s) => {
const view = new AccessTokenView();
view.id = s.id;
view.name = await this.encryptService.decryptToUtf8(new EncString(s.name), orgKey);
view.scopes = s.scopes;
view.expireAt = s.expireAt ? new Date(s.expireAt) : null;
view.creationDate = new Date(s.creationDate);
view.revisionDate = new Date(s.revisionDate);
return view;
})
);
}
}