diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index a8ce05f180..65d19a8b80 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -36,7 +36,6 @@ ./libs/angular/src/interfaces/selectOptions.ts ./libs/components/src/stories/Introduction.stories.mdx ./libs/common/spec/misc/logInStrategies/logIn.strategy.spec.ts -./libs/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts ./libs/common/spec/misc/logInStrategies/passwordLogIn.strategy.spec.ts ./libs/common/spec/misc/logInStrategies/ssoLogIn.strategy.spec.ts ./libs/common/spec/web/services/webCryptoFunction.service.spec.ts @@ -60,7 +59,6 @@ ./libs/common/spec/services/consoleLog.service.spec.ts ./libs/common/src/misc/logInStrategies/ssoLogin.strategy.ts ./libs/common/src/misc/logInStrategies/passwordLogin.strategy.ts -./libs/common/src/misc/logInStrategies/apiLogin.strategy.ts ./libs/common/src/misc/logInStrategies/passwordlessLogin.strategy.ts ./libs/common/src/misc/logInStrategies/logIn.strategy.ts ./libs/common/src/misc/nodeUtils.ts diff --git a/libs/angular/src/components/two-factor.component.ts b/libs/angular/src/components/two-factor.component.ts index f61e54710b..28799df660 100644 --- a/libs/angular/src/components/two-factor.component.ts +++ b/libs/angular/src/components/two-factor.component.ts @@ -281,12 +281,12 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI return ( this.authService.authingWithPassword() || this.authService.authingWithSso() || - this.authService.authingWithApiKey() || + this.authService.authingWithUserApiKey() || this.authService.authingWithPasswordless() ); } get needsLock(): boolean { - return this.authService.authingWithSso() || this.authService.authingWithApiKey(); + return this.authService.authingWithSso() || this.authService.authingWithUserApiKey(); } } diff --git a/libs/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts b/libs/common/spec/misc/logInStrategies/user-api-login.strategy.spec.ts similarity index 90% rename from libs/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts rename to libs/common/spec/misc/logInStrategies/user-api-login.strategy.spec.ts index 6e80ffa291..bc61d2c7e2 100644 --- a/libs/common/spec/misc/logInStrategies/apiLogIn.strategy.spec.ts +++ b/libs/common/spec/misc/logInStrategies/user-api-login.strategy.spec.ts @@ -12,13 +12,13 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti import { StateService } from "@bitwarden/common/abstractions/state.service"; import { TokenService } from "@bitwarden/common/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/abstractions/twoFactor.service"; -import { ApiLogInStrategy } from "@bitwarden/common/misc/logInStrategies/apiLogin.strategy"; +import { UserApiLogInStrategy } from "@bitwarden/common/misc/logInStrategies/user-api-login.strategy"; import { Utils } from "@bitwarden/common/misc/utils"; -import { ApiLogInCredentials } from "@bitwarden/common/models/domain/log-in-credentials"; +import { UserApiLogInCredentials } from "@bitwarden/common/models/domain/log-in-credentials"; import { identityTokenResponseFactory } from "./logIn.strategy.spec"; -describe("ApiLogInStrategy", () => { +describe("UserApiLogInStrategy", () => { let cryptoService: SubstituteOf; let apiService: SubstituteOf; let tokenService: SubstituteOf; @@ -31,8 +31,8 @@ describe("ApiLogInStrategy", () => { let stateService: SubstituteOf; let twoFactorService: SubstituteOf; - let apiLogInStrategy: ApiLogInStrategy; - let credentials: ApiLogInCredentials; + let apiLogInStrategy: UserApiLogInStrategy; + let credentials: UserApiLogInCredentials; const deviceId = Utils.newGuid(); const keyConnectorUrl = "KEY_CONNECTOR_URL"; @@ -55,7 +55,7 @@ describe("ApiLogInStrategy", () => { appIdService.getAppId().resolves(deviceId); tokenService.getTwoFactorToken().resolves(null); - apiLogInStrategy = new ApiLogInStrategy( + apiLogInStrategy = new UserApiLogInStrategy( cryptoService, apiService, tokenService, @@ -69,7 +69,7 @@ describe("ApiLogInStrategy", () => { keyConnectorService ); - credentials = new ApiLogInCredentials(apiClientId, apiClientSecret); + credentials = new UserApiLogInCredentials(apiClientId, apiClientSecret); }); it("sends api key credentials to the server", async () => { diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index 74f9edebd6..a8e2f45283 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -24,9 +24,9 @@ import { EmergencyAccessUpdateRequest } from "../models/request/emergency-access import { EventRequest } from "../models/request/event.request"; import { GroupRequest } from "../models/request/group.request"; import { IapCheckRequest } from "../models/request/iap-check.request"; -import { ApiTokenRequest } from "../models/request/identity-token/api-token.request"; import { PasswordTokenRequest } from "../models/request/identity-token/password-token.request"; import { SsoTokenRequest } from "../models/request/identity-token/sso-token.request"; +import { UserApiTokenRequest } from "../models/request/identity-token/user-api-token.request"; import { ImportCiphersRequest } from "../models/request/import-ciphers.request"; import { ImportOrganizationCiphersRequest } from "../models/request/import-organization-ciphers.request"; import { KdfRequest } from "../models/request/kdf.request"; @@ -175,7 +175,7 @@ export abstract class ApiService { ) => Promise; postIdentityToken: ( - request: PasswordTokenRequest | SsoTokenRequest | ApiTokenRequest + request: PasswordTokenRequest | SsoTokenRequest | UserApiTokenRequest ) => Promise; refreshIdentityToken: () => Promise; diff --git a/libs/common/src/abstractions/auth.service.ts b/libs/common/src/abstractions/auth.service.ts index cadc7bb60b..ca75e273b5 100644 --- a/libs/common/src/abstractions/auth.service.ts +++ b/libs/common/src/abstractions/auth.service.ts @@ -3,7 +3,7 @@ import { Observable } from "rxjs"; import { AuthenticationStatus } from "../enums/authenticationStatus"; import { AuthResult } from "../models/domain/auth-result"; import { - ApiLogInCredentials, + UserApiLogInCredentials, PasswordLogInCredentials, SsoLogInCredentials, PasswordlessLogInCredentials, @@ -20,7 +20,7 @@ export abstract class AuthService { logIn: ( credentials: - | ApiLogInCredentials + | UserApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials | PasswordlessLogInCredentials @@ -31,7 +31,7 @@ export abstract class AuthService { ) => Promise; logOut: (callback: () => void) => void; makePreloginKey: (masterPassword: string, email: string) => Promise; - authingWithApiKey: () => boolean; + authingWithUserApiKey: () => boolean; authingWithSso: () => boolean; authingWithPassword: () => boolean; authingWithPasswordless: () => boolean; diff --git a/libs/common/src/enums/authenticationType.ts b/libs/common/src/enums/authenticationType.ts index 5133c4f648..531c571b46 100644 --- a/libs/common/src/enums/authenticationType.ts +++ b/libs/common/src/enums/authenticationType.ts @@ -1,6 +1,6 @@ export enum AuthenticationType { Password = 0, Sso = 1, - Api = 2, + UserApi = 2, Passwordless = 3, } diff --git a/libs/common/src/misc/logInStrategies/logIn.strategy.ts b/libs/common/src/misc/logInStrategies/logIn.strategy.ts index 8ac3ea2b55..b0cf06e9f9 100644 --- a/libs/common/src/misc/logInStrategies/logIn.strategy.ts +++ b/libs/common/src/misc/logInStrategies/logIn.strategy.ts @@ -11,23 +11,23 @@ import { TwoFactorProviderType } from "../../enums/twoFactorProviderType"; import { Account, AccountProfile, AccountTokens } from "../../models/domain/account"; import { AuthResult } from "../../models/domain/auth-result"; import { - ApiLogInCredentials, + UserApiLogInCredentials, PasswordLogInCredentials, SsoLogInCredentials, PasswordlessLogInCredentials, } from "../../models/domain/log-in-credentials"; import { DeviceRequest } from "../../models/request/device.request"; -import { ApiTokenRequest } from "../../models/request/identity-token/api-token.request"; import { PasswordTokenRequest } from "../../models/request/identity-token/password-token.request"; import { SsoTokenRequest } from "../../models/request/identity-token/sso-token.request"; import { TokenTwoFactorRequest } from "../../models/request/identity-token/token-two-factor.request"; +import { UserApiTokenRequest } from "../../models/request/identity-token/user-api-token.request"; import { KeysRequest } from "../../models/request/keys.request"; import { IdentityCaptchaResponse } from "../../models/response/identity-captcha.response"; import { IdentityTokenResponse } from "../../models/response/identity-token.response"; import { IdentityTwoFactorResponse } from "../../models/response/identity-two-factor.response"; export abstract class LogInStrategy { - protected abstract tokenRequest: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest; + protected abstract tokenRequest: UserApiTokenRequest | PasswordTokenRequest | SsoTokenRequest; protected captchaBypassToken: string = null; constructor( @@ -44,7 +44,7 @@ export abstract class LogInStrategy { abstract logIn( credentials: - | ApiLogInCredentials + | UserApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials | PasswordlessLogInCredentials diff --git a/libs/common/src/misc/logInStrategies/apiLogin.strategy.ts b/libs/common/src/misc/logInStrategies/user-api-login.strategy.ts similarity index 85% rename from libs/common/src/misc/logInStrategies/apiLogin.strategy.ts rename to libs/common/src/misc/logInStrategies/user-api-login.strategy.ts index a60735343a..7b435c74fd 100644 --- a/libs/common/src/misc/logInStrategies/apiLogin.strategy.ts +++ b/libs/common/src/misc/logInStrategies/user-api-login.strategy.ts @@ -9,14 +9,14 @@ import { PlatformUtilsService } from "../../abstractions/platformUtils.service"; import { StateService } from "../../abstractions/state.service"; import { TokenService } from "../../abstractions/token.service"; import { TwoFactorService } from "../../abstractions/twoFactor.service"; -import { ApiLogInCredentials } from "../../models/domain/log-in-credentials"; -import { ApiTokenRequest } from "../../models/request/identity-token/api-token.request"; +import { UserApiLogInCredentials } from "../../models/domain/log-in-credentials"; +import { UserApiTokenRequest } from "../../models/request/identity-token/user-api-token.request"; import { IdentityTokenResponse } from "../../models/response/identity-token.response"; import { LogInStrategy } from "./logIn.strategy"; -export class ApiLogInStrategy extends LogInStrategy { - tokenRequest: ApiTokenRequest; +export class UserApiLogInStrategy extends LogInStrategy { + tokenRequest: UserApiTokenRequest; constructor( cryptoService: CryptoService, @@ -51,8 +51,8 @@ export class ApiLogInStrategy extends LogInStrategy { } } - async logIn(credentials: ApiLogInCredentials) { - this.tokenRequest = new ApiTokenRequest( + async logIn(credentials: UserApiLogInCredentials) { + this.tokenRequest = new UserApiTokenRequest( credentials.clientId, credentials.clientSecret, await this.buildTwoFactor(), diff --git a/libs/common/src/models/domain/log-in-credentials.ts b/libs/common/src/models/domain/log-in-credentials.ts index 46f2fe5f82..81323934bf 100644 --- a/libs/common/src/models/domain/log-in-credentials.ts +++ b/libs/common/src/models/domain/log-in-credentials.ts @@ -26,8 +26,8 @@ export class SsoLogInCredentials { ) {} } -export class ApiLogInCredentials { - readonly type = AuthenticationType.Api; +export class UserApiLogInCredentials { + readonly type = AuthenticationType.UserApi; constructor(public clientId: string, public clientSecret: string) {} } diff --git a/libs/common/src/models/request/identity-token/token.request.ts b/libs/common/src/models/request/identity-token/token.request.ts index 91007ce342..32becd222a 100644 --- a/libs/common/src/models/request/identity-token/token.request.ts +++ b/libs/common/src/models/request/identity-token/token.request.ts @@ -42,10 +42,12 @@ export abstract class TokenRequest { obj.authRequest = this.passwordlessAuthRequest; } - if (this.twoFactor.token && this.twoFactor.provider != null) { - obj.twoFactorToken = this.twoFactor.token; - obj.twoFactorProvider = this.twoFactor.provider; - obj.twoFactorRemember = this.twoFactor.remember ? "1" : "0"; + if (this.twoFactor) { + if (this.twoFactor.token && this.twoFactor.provider != null) { + obj.twoFactorToken = this.twoFactor.token; + obj.twoFactorProvider = this.twoFactor.provider; + obj.twoFactorRemember = this.twoFactor.remember ? "1" : "0"; + } } return obj; diff --git a/libs/common/src/models/request/identity-token/api-token.request.ts b/libs/common/src/models/request/identity-token/user-api-token.request.ts similarity index 91% rename from libs/common/src/models/request/identity-token/api-token.request.ts rename to libs/common/src/models/request/identity-token/user-api-token.request.ts index 60c8b6d381..15a9bbfe68 100644 --- a/libs/common/src/models/request/identity-token/api-token.request.ts +++ b/libs/common/src/models/request/identity-token/user-api-token.request.ts @@ -3,7 +3,7 @@ import { DeviceRequest } from "../device.request"; import { TokenTwoFactorRequest } from "./token-two-factor.request"; import { TokenRequest } from "./token.request"; -export class ApiTokenRequest extends TokenRequest { +export class UserApiTokenRequest extends TokenRequest { constructor( public clientId: string, public clientSecret: string, diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index 6c15d85c0d..6b660bb367 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -31,10 +31,10 @@ import { EmergencyAccessUpdateRequest } from "../models/request/emergency-access import { EventRequest } from "../models/request/event.request"; import { GroupRequest } from "../models/request/group.request"; import { IapCheckRequest } from "../models/request/iap-check.request"; -import { ApiTokenRequest } from "../models/request/identity-token/api-token.request"; import { PasswordTokenRequest } from "../models/request/identity-token/password-token.request"; import { SsoTokenRequest } from "../models/request/identity-token/sso-token.request"; import { TokenTwoFactorRequest } from "../models/request/identity-token/token-two-factor.request"; +import { UserApiTokenRequest } from "../models/request/identity-token/user-api-token.request"; import { ImportCiphersRequest } from "../models/request/import-ciphers.request"; import { ImportOrganizationCiphersRequest } from "../models/request/import-organization-ciphers.request"; import { KdfRequest } from "../models/request/kdf.request"; @@ -206,7 +206,7 @@ export class ApiService implements ApiServiceAbstraction { // Auth APIs async postIdentityToken( - request: ApiTokenRequest | PasswordTokenRequest | SsoTokenRequest + request: UserApiTokenRequest | PasswordTokenRequest | SsoTokenRequest ): Promise { const headers = new Headers({ "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", @@ -219,7 +219,7 @@ export class ApiService implements ApiServiceAbstraction { request.alterIdentityTokenHeaders(headers); const identityToken = - request instanceof ApiTokenRequest + request instanceof UserApiTokenRequest ? request.toIdentityToken() : request.toIdentityToken(this.platformUtilsService.getClientType()); @@ -2271,8 +2271,7 @@ export class ApiService implements ApiServiceAbstraction { const appId = await this.appIdService.getAppId(); const deviceRequest = new DeviceRequest(appId, this.platformUtilsService); - - const tokenRequest = new ApiTokenRequest( + const tokenRequest = new UserApiTokenRequest( clientId, clientSecret, new TokenTwoFactorRequest(), diff --git a/libs/common/src/services/auth.service.ts b/libs/common/src/services/auth.service.ts index 4a851fb13d..4e97f70111 100644 --- a/libs/common/src/services/auth.service.ts +++ b/libs/common/src/services/auth.service.ts @@ -17,13 +17,13 @@ import { AuthenticationStatus } from "../enums/authenticationStatus"; import { AuthenticationType } from "../enums/authenticationType"; import { KdfType } from "../enums/kdfType"; import { KeySuffixOptions } from "../enums/keySuffixOptions"; -import { ApiLogInStrategy } from "../misc/logInStrategies/apiLogin.strategy"; import { PasswordLogInStrategy } from "../misc/logInStrategies/passwordLogin.strategy"; import { PasswordlessLogInStrategy } from "../misc/logInStrategies/passwordlessLogin.strategy"; import { SsoLogInStrategy } from "../misc/logInStrategies/ssoLogin.strategy"; +import { UserApiLogInStrategy } from "../misc/logInStrategies/user-api-login.strategy"; import { AuthResult } from "../models/domain/auth-result"; import { - ApiLogInCredentials, + UserApiLogInCredentials, PasswordLogInCredentials, SsoLogInCredentials, PasswordlessLogInCredentials, @@ -67,7 +67,7 @@ export class AuthService implements AuthServiceAbstraction { } private logInStrategy: - | ApiLogInStrategy + | UserApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy | PasswordlessLogInStrategy; @@ -92,7 +92,7 @@ export class AuthService implements AuthServiceAbstraction { async logIn( credentials: - | ApiLogInCredentials + | UserApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials | PasswordlessLogInCredentials @@ -100,7 +100,7 @@ export class AuthService implements AuthServiceAbstraction { this.clearState(); let strategy: - | ApiLogInStrategy + | UserApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy | PasswordlessLogInStrategy; @@ -134,8 +134,8 @@ export class AuthService implements AuthServiceAbstraction { this.keyConnectorService ); break; - case AuthenticationType.Api: - strategy = new ApiLogInStrategy( + case AuthenticationType.UserApi: + strategy = new UserApiLogInStrategy( this.cryptoService, this.apiService, this.tokenService, @@ -203,8 +203,8 @@ export class AuthService implements AuthServiceAbstraction { this.messagingService.send("loggedOut"); } - authingWithApiKey(): boolean { - return this.logInStrategy instanceof ApiLogInStrategy; + authingWithUserApiKey(): boolean { + return this.logInStrategy instanceof UserApiLogInStrategy; } authingWithSso(): boolean { @@ -272,7 +272,7 @@ export class AuthService implements AuthServiceAbstraction { private saveState( strategy: - | ApiLogInStrategy + | UserApiLogInStrategy | PasswordLogInStrategy | SsoLogInStrategy | PasswordlessLogInStrategy diff --git a/libs/node/src/cli/commands/login.command.ts b/libs/node/src/cli/commands/login.command.ts index dfff7b9ad2..413b5add5e 100644 --- a/libs/node/src/cli/commands/login.command.ts +++ b/libs/node/src/cli/commands/login.command.ts @@ -21,7 +21,7 @@ import { NodeUtils } from "@bitwarden/common/misc/nodeUtils"; import { Utils } from "@bitwarden/common/misc/utils"; import { AuthResult } from "@bitwarden/common/models/domain/auth-result"; import { - ApiLogInCredentials, + UserApiLogInCredentials, PasswordLogInCredentials, SsoLogInCredentials, } from "@bitwarden/common/models/domain/log-in-credentials"; @@ -160,7 +160,12 @@ export class LoginCommand { let response: AuthResult = null; if (clientId != null && clientSecret != null) { - response = await this.authService.logIn(new ApiLogInCredentials(clientId, clientSecret)); + if (!clientId.startsWith("user")) { + return Response.error("Invalid API Key; Organization API Key currently not supported"); + } + response = await this.authService.logIn( + new UserApiLogInCredentials(clientId, clientSecret) + ); } else if (ssoCode != null && ssoCodeVerifier != null) { response = await this.authService.logIn( new SsoLogInCredentials(