2022-10-10 17:19:01 +02:00
|
|
|
// eslint-disable-next-line no-restricted-imports
|
2022-02-01 00:51:32 +01:00
|
|
|
import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute";
|
|
|
|
|
2022-06-14 17:10:53 +02:00
|
|
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|
|
|
import { AppIdService } from "@bitwarden/common/abstractions/appId.service";
|
|
|
|
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
|
|
|
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
|
|
|
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
|
|
|
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
|
|
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
|
|
|
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
|
|
|
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 { Utils } from "@bitwarden/common/misc/utils";
|
|
|
|
import { ApiLogInCredentials } from "@bitwarden/common/models/domain/logInCredentials";
|
2022-02-01 00:51:32 +01:00
|
|
|
|
|
|
|
import { identityTokenResponseFactory } from "./logIn.strategy.spec";
|
|
|
|
|
|
|
|
describe("ApiLogInStrategy", () => {
|
|
|
|
let cryptoService: SubstituteOf<CryptoService>;
|
|
|
|
let apiService: SubstituteOf<ApiService>;
|
|
|
|
let tokenService: SubstituteOf<TokenService>;
|
|
|
|
let appIdService: SubstituteOf<AppIdService>;
|
|
|
|
let platformUtilsService: SubstituteOf<PlatformUtilsService>;
|
|
|
|
let messagingService: SubstituteOf<MessagingService>;
|
|
|
|
let logService: SubstituteOf<LogService>;
|
|
|
|
let environmentService: SubstituteOf<EnvironmentService>;
|
|
|
|
let keyConnectorService: SubstituteOf<KeyConnectorService>;
|
|
|
|
let stateService: SubstituteOf<StateService>;
|
|
|
|
let twoFactorService: SubstituteOf<TwoFactorService>;
|
|
|
|
|
|
|
|
let apiLogInStrategy: ApiLogInStrategy;
|
|
|
|
let credentials: ApiLogInCredentials;
|
|
|
|
|
|
|
|
const deviceId = Utils.newGuid();
|
|
|
|
const keyConnectorUrl = "KEY_CONNECTOR_URL";
|
|
|
|
const apiClientId = "API_CLIENT_ID";
|
|
|
|
const apiClientSecret = "API_CLIENT_SECRET";
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
cryptoService = Substitute.for<CryptoService>();
|
|
|
|
apiService = Substitute.for<ApiService>();
|
|
|
|
tokenService = Substitute.for<TokenService>();
|
|
|
|
appIdService = Substitute.for<AppIdService>();
|
|
|
|
platformUtilsService = Substitute.for<PlatformUtilsService>();
|
|
|
|
messagingService = Substitute.for<MessagingService>();
|
|
|
|
logService = Substitute.for<LogService>();
|
|
|
|
environmentService = Substitute.for<EnvironmentService>();
|
|
|
|
stateService = Substitute.for<StateService>();
|
|
|
|
keyConnectorService = Substitute.for<KeyConnectorService>();
|
|
|
|
twoFactorService = Substitute.for<TwoFactorService>();
|
|
|
|
|
|
|
|
appIdService.getAppId().resolves(deviceId);
|
|
|
|
tokenService.getTwoFactorToken().resolves(null);
|
|
|
|
|
|
|
|
apiLogInStrategy = new ApiLogInStrategy(
|
|
|
|
cryptoService,
|
|
|
|
apiService,
|
|
|
|
tokenService,
|
|
|
|
appIdService,
|
|
|
|
platformUtilsService,
|
|
|
|
messagingService,
|
|
|
|
logService,
|
|
|
|
stateService,
|
|
|
|
twoFactorService,
|
|
|
|
environmentService,
|
|
|
|
keyConnectorService
|
|
|
|
);
|
|
|
|
|
|
|
|
credentials = new ApiLogInCredentials(apiClientId, apiClientSecret);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("sends api key credentials to the server", async () => {
|
|
|
|
apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory());
|
|
|
|
await apiLogInStrategy.logIn(credentials);
|
|
|
|
|
|
|
|
apiService.received(1).postIdentityToken(
|
|
|
|
Arg.is((actual) => {
|
|
|
|
const apiTokenRequest = actual as any;
|
|
|
|
return (
|
|
|
|
apiTokenRequest.clientId === apiClientId &&
|
|
|
|
apiTokenRequest.clientSecret === apiClientSecret &&
|
|
|
|
apiTokenRequest.device.identifier === deviceId &&
|
|
|
|
apiTokenRequest.twoFactor.provider == null &&
|
|
|
|
apiTokenRequest.twoFactor.token == null &&
|
|
|
|
apiTokenRequest.captchaResponse == null
|
|
|
|
);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("sets the local environment after a successful login", async () => {
|
|
|
|
apiService.postIdentityToken(Arg.any()).resolves(identityTokenResponseFactory());
|
|
|
|
|
|
|
|
await apiLogInStrategy.logIn(credentials);
|
|
|
|
|
|
|
|
stateService.received(1).setApiKeyClientId(apiClientId);
|
|
|
|
stateService.received(1).setApiKeyClientSecret(apiClientSecret);
|
|
|
|
stateService.received(1).addAccount(Arg.any());
|
|
|
|
});
|
|
|
|
|
|
|
|
it("gets and sets the Key Connector key from environmentUrl", async () => {
|
|
|
|
const tokenResponse = identityTokenResponseFactory();
|
|
|
|
tokenResponse.apiUseKeyConnector = true;
|
|
|
|
|
|
|
|
apiService.postIdentityToken(Arg.any()).resolves(tokenResponse);
|
|
|
|
environmentService.getKeyConnectorUrl().returns(keyConnectorUrl);
|
|
|
|
|
|
|
|
await apiLogInStrategy.logIn(credentials);
|
|
|
|
|
|
|
|
keyConnectorService.received(1).getAndSetKey(keyConnectorUrl);
|
|
|
|
});
|
|
|
|
});
|