mirror of
https://github.com/bitwarden/browser
synced 2026-01-07 11:03:30 +00:00
Pm-10953/add-user-context-to-sync-replaces (#10627)
* Require userId for setting masterKeyEncryptedUserKey * Replace folders for specified user * Require userId for collection replace * Cipher Replace requires userId * Require UserId to update equivalent domains * Require userId for policy replace * sync state updates between fake state for better testing * Revert to public observable tests Since they now sync, we can test single-user updates impacting active user observables * Do not init fake states through sync Do not sync initial null values, that might wipe out already existing data. * Require userId for Send replace * Include userId for organization replace * Require userId for billing sync data * Require user Id for key connector sync data * Allow decode of token by userId * Require userId for synced key connector updates * Add userId to policy setting during organization invite accept * Fix cli * Handle null userId --------- Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
This commit is contained in:
@@ -78,9 +78,9 @@ describe("KeyConnectorService", () => {
|
||||
|
||||
const newValue = true;
|
||||
|
||||
await keyConnectorService.setUsesKeyConnector(newValue);
|
||||
await keyConnectorService.setUsesKeyConnector(newValue, mockUserId);
|
||||
|
||||
expect(await keyConnectorService.getUsesKeyConnector()).toBe(newValue);
|
||||
expect(await keyConnectorService.getUsesKeyConnector(mockUserId)).toBe(newValue);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -185,7 +185,7 @@ describe("KeyConnectorService", () => {
|
||||
const state = stateProvider.activeUser.getFake(USES_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const result = await keyConnectorService.userNeedsMigration();
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
@@ -197,7 +197,7 @@ describe("KeyConnectorService", () => {
|
||||
|
||||
const state = stateProvider.activeUser.getFake(USES_KEY_CONNECTOR);
|
||||
state.nextState(true);
|
||||
const result = await keyConnectorService.userNeedsMigration();
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
@@ -69,25 +69,25 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
);
|
||||
}
|
||||
|
||||
async setUsesKeyConnector(usesKeyConnector: boolean) {
|
||||
await this.usesKeyConnectorState.update(() => usesKeyConnector);
|
||||
async setUsesKeyConnector(usesKeyConnector: boolean, userId: UserId) {
|
||||
await this.stateProvider.getUser(userId, USES_KEY_CONNECTOR).update(() => usesKeyConnector);
|
||||
}
|
||||
|
||||
getUsesKeyConnector(): Promise<boolean> {
|
||||
return firstValueFrom(this.usesKeyConnectorState.state$);
|
||||
getUsesKeyConnector(userId: UserId): Promise<boolean> {
|
||||
return firstValueFrom(this.stateProvider.getUserState$(USES_KEY_CONNECTOR, userId));
|
||||
}
|
||||
|
||||
async userNeedsMigration() {
|
||||
const loggedInUsingSso = await this.tokenService.getIsExternal();
|
||||
const requiredByOrganization = (await this.getManagingOrganization()) != null;
|
||||
const userIsNotUsingKeyConnector = !(await this.getUsesKeyConnector());
|
||||
async userNeedsMigration(userId: UserId) {
|
||||
const loggedInUsingSso = await this.tokenService.getIsExternal(userId);
|
||||
const requiredByOrganization = (await this.getManagingOrganization(userId)) != null;
|
||||
const userIsNotUsingKeyConnector = !(await this.getUsesKeyConnector(userId));
|
||||
|
||||
return loggedInUsingSso && requiredByOrganization && userIsNotUsingKeyConnector;
|
||||
}
|
||||
|
||||
async migrateUser() {
|
||||
const organization = await this.getManagingOrganization();
|
||||
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
|
||||
async migrateUser(userId?: UserId) {
|
||||
userId ??= (await firstValueFrom(this.accountService.activeAccount$))?.id;
|
||||
const organization = await this.getManagingOrganization(userId);
|
||||
const masterKey = await firstValueFrom(this.masterPasswordService.masterKey$(userId));
|
||||
const keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.encKeyB64);
|
||||
|
||||
@@ -115,8 +115,8 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
}
|
||||
}
|
||||
|
||||
async getManagingOrganization(): Promise<Organization> {
|
||||
const orgs = await this.organizationService.getAll();
|
||||
async getManagingOrganization(userId?: UserId): Promise<Organization> {
|
||||
const orgs = await this.organizationService.getAll(userId);
|
||||
return orgs.find(
|
||||
(o) =>
|
||||
o.keyConnectorEnabled &&
|
||||
@@ -178,16 +178,16 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
await this.apiService.postSetKeyConnectorKey(setPasswordRequest);
|
||||
}
|
||||
|
||||
async setConvertAccountRequired(status: boolean) {
|
||||
await this.convertAccountToKeyConnectorState.update(() => status);
|
||||
async setConvertAccountRequired(status: boolean, userId?: UserId) {
|
||||
await this.stateProvider.setUserState(CONVERT_ACCOUNT_TO_KEY_CONNECTOR, status, userId);
|
||||
}
|
||||
|
||||
getConvertAccountRequired(): Promise<boolean> {
|
||||
return firstValueFrom(this.convertAccountToKeyConnectorState.state$);
|
||||
}
|
||||
|
||||
async removeConvertAccountRequired() {
|
||||
await this.setConvertAccountRequired(null);
|
||||
async removeConvertAccountRequired(userId?: UserId) {
|
||||
await this.setConvertAccountRequired(null, userId);
|
||||
}
|
||||
|
||||
private handleKeyConnectorError(e: any) {
|
||||
|
||||
@@ -126,7 +126,7 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Act
|
||||
const result = await firstValueFrom(tokenService.hasAccessToken$(userIdFromAccessToken));
|
||||
@@ -139,11 +139,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Act
|
||||
const result = await firstValueFrom(tokenService.hasAccessToken$(userIdFromAccessToken));
|
||||
@@ -156,7 +156,7 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, "encryptedAccessToken"]);
|
||||
.nextState("encryptedAccessToken");
|
||||
|
||||
secureStorageService.get.mockResolvedValue(accessTokenKeyB64);
|
||||
|
||||
@@ -282,7 +282,7 @@ describe("TokenService", () => {
|
||||
// For testing purposes, let's assume that the access token is already in memory
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
keyGenerationService.createKey.mockResolvedValue(accessTokenKey);
|
||||
|
||||
@@ -411,9 +411,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns null when no access token is found in memory, disk, or secure storage", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getAccessToken();
|
||||
@@ -429,18 +427,16 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// set disk to undefined
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
if (!userId) {
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
}
|
||||
|
||||
// Act
|
||||
@@ -459,17 +455,15 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
if (!userId) {
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
}
|
||||
|
||||
// Act
|
||||
@@ -498,20 +492,18 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, "encryptedAccessToken"]);
|
||||
.nextState("encryptedAccessToken");
|
||||
|
||||
secureStorageService.get.mockResolvedValue(accessTokenKeyB64);
|
||||
encryptService.decryptToUtf8.mockResolvedValue("decryptedAccessToken");
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
if (!userId) {
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
}
|
||||
|
||||
// Act
|
||||
@@ -534,17 +526,15 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
if (!userId) {
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
}
|
||||
|
||||
// No access token key set
|
||||
@@ -564,11 +554,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, encryptedAccessToken]);
|
||||
.nextState(encryptedAccessToken);
|
||||
|
||||
// No access token key set
|
||||
|
||||
@@ -596,11 +586,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, encryptedAccessToken]);
|
||||
.nextState(encryptedAccessToken);
|
||||
|
||||
// Mock linux secure storage error
|
||||
const secureStorageError = "Secure storage error";
|
||||
@@ -655,17 +645,15 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
if (!userId) {
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
}
|
||||
|
||||
// Act
|
||||
@@ -688,8 +676,32 @@ describe("TokenService", () => {
|
||||
});
|
||||
|
||||
describe("decodeAccessToken", () => {
|
||||
it("retrieves the requested user's token when the passed in parameter is a Guid", async () => {
|
||||
// Arrange
|
||||
tokenService.getAccessToken = jest.fn().mockResolvedValue(accessTokenJwt);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.decodeAccessToken(userIdFromAccessToken);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(accessTokenDecoded);
|
||||
expect(tokenService.getAccessToken).toHaveBeenCalledWith(userIdFromAccessToken);
|
||||
});
|
||||
|
||||
it("decodes the given token when a string is passed in that is not a Guid", async () => {
|
||||
// Arrange
|
||||
tokenService.getAccessToken = jest.fn();
|
||||
|
||||
// Act
|
||||
const result = await tokenService.decodeAccessToken(accessTokenJwt);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(accessTokenDecoded);
|
||||
expect(tokenService.getAccessToken).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("throws an error when no access token is provided or retrievable from state", async () => {
|
||||
// Access
|
||||
// Arrange
|
||||
tokenService.getAccessToken = jest.fn().mockResolvedValue(null);
|
||||
|
||||
// Act
|
||||
@@ -1194,7 +1206,7 @@ describe("TokenService", () => {
|
||||
|
||||
// Act
|
||||
// note: don't await here because we want to test the error
|
||||
const result = tokenService.getIsExternal();
|
||||
const result = tokenService.getIsExternal(null);
|
||||
// Assert
|
||||
await expect(result).rejects.toThrow("Failed to decode access token: Mock error");
|
||||
});
|
||||
@@ -1210,7 +1222,7 @@ describe("TokenService", () => {
|
||||
.mockResolvedValue(accessTokenDecodedWithoutExternalAmr);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getIsExternal();
|
||||
const result = await tokenService.getIsExternal(null);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(false);
|
||||
@@ -1227,11 +1239,22 @@ describe("TokenService", () => {
|
||||
.mockResolvedValue(accessTokenDecodedWithExternalAmr);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getIsExternal();
|
||||
const result = await tokenService.getIsExternal(null);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
||||
it("passes the requested userId to decode", async () => {
|
||||
// Arrange
|
||||
tokenService.decodeAccessToken = jest.fn().mockResolvedValue(accessTokenDecoded);
|
||||
|
||||
// Act
|
||||
await tokenService.getIsExternal(userIdFromAccessToken);
|
||||
|
||||
// Assert
|
||||
expect(tokenService.decodeAccessToken).toHaveBeenCalledWith(userIdFromAccessToken);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1326,11 +1349,11 @@ describe("TokenService", () => {
|
||||
// For testing purposes, let's assume that the token is already in disk and memory
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// We immediately call to get the refresh token from secure storage after setting it to ensure it was set.
|
||||
secureStorageService.get.mockResolvedValue(refreshToken);
|
||||
@@ -1423,11 +1446,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, accessTokenJwt]);
|
||||
.nextState(accessTokenJwt);
|
||||
|
||||
// Mock linux secure storage error
|
||||
const secureStorageError = "Secure storage error";
|
||||
@@ -1480,11 +1503,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, ACCESS_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, encryptedAccessToken]);
|
||||
.nextState(encryptedAccessToken);
|
||||
|
||||
secureStorageService.get.mockResolvedValue(accessTokenKeyB64);
|
||||
encryptService.decryptToUtf8.mockRejectedValue(new Error("Decryption error"));
|
||||
@@ -1520,9 +1543,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns null when no refresh token is found in memory, disk, or secure storage", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await (tokenService as any).getRefreshToken();
|
||||
@@ -1535,16 +1556,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken();
|
||||
@@ -1557,11 +1576,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken(userIdFromAccessToken);
|
||||
@@ -1575,16 +1594,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken();
|
||||
@@ -1596,11 +1613,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken(userIdFromAccessToken);
|
||||
@@ -1619,18 +1636,16 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
secureStorageService.get.mockResolvedValue(refreshToken);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken();
|
||||
@@ -1643,11 +1658,11 @@ describe("TokenService", () => {
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
secureStorageService.get.mockResolvedValue(refreshToken);
|
||||
|
||||
@@ -1661,11 +1676,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken(userIdFromAccessToken);
|
||||
@@ -1681,16 +1696,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getRefreshToken();
|
||||
@@ -1719,11 +1732,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
secureStorageService.get.mockResolvedValue(null);
|
||||
|
||||
@@ -1743,11 +1756,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
const secureStorageSvcMockErrorMsg = "Secure storage retrieval error";
|
||||
|
||||
@@ -1792,11 +1805,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, REFRESH_TOKEN_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, refreshToken]);
|
||||
.nextState(refreshToken);
|
||||
|
||||
// Act
|
||||
await (tokenService as any).clearRefreshToken(userIdFromAccessToken);
|
||||
@@ -1833,9 +1846,7 @@ describe("TokenService", () => {
|
||||
it("should throw an error if the vault timeout is missing", async () => {
|
||||
// Arrange
|
||||
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = tokenService.setClientId(clientId, VaultTimeoutAction.Lock, null);
|
||||
@@ -1847,9 +1858,7 @@ describe("TokenService", () => {
|
||||
it("should throw an error if the vault timeout action is missing", async () => {
|
||||
// Arrange
|
||||
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = tokenService.setClientId(clientId, null, VaultTimeoutStringType.Never);
|
||||
@@ -1861,9 +1870,7 @@ describe("TokenService", () => {
|
||||
describe("Memory storage tests", () => {
|
||||
it("sets the client id in memory when there is an active user in global state", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await tokenService.setClientId(clientId, memoryVaultTimeoutAction, memoryVaultTimeout);
|
||||
@@ -1895,9 +1902,7 @@ describe("TokenService", () => {
|
||||
describe("Disk storage tests", () => {
|
||||
it("sets the client id in disk when there is an active user in global state", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await tokenService.setClientId(clientId, diskVaultTimeoutAction, diskVaultTimeout);
|
||||
@@ -1935,9 +1940,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns null when no client id is found in memory or disk", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientId();
|
||||
@@ -1950,17 +1953,15 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// set disk to undefined
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientId();
|
||||
@@ -1973,12 +1974,12 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// set disk to undefined
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientId(userIdFromAccessToken);
|
||||
@@ -1992,16 +1993,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientId();
|
||||
@@ -2013,11 +2012,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientId(userIdFromAccessToken);
|
||||
@@ -2040,11 +2039,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// Act
|
||||
await (tokenService as any).clearClientId(userIdFromAccessToken);
|
||||
@@ -2062,16 +2061,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_ID_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientId]);
|
||||
.nextState(clientId);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await (tokenService as any).clearClientId();
|
||||
@@ -2106,9 +2103,7 @@ describe("TokenService", () => {
|
||||
it("should throw an error if the vault timeout is missing", async () => {
|
||||
// Arrange
|
||||
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = tokenService.setClientSecret(clientSecret, VaultTimeoutAction.Lock, null);
|
||||
@@ -2120,9 +2115,7 @@ describe("TokenService", () => {
|
||||
it("should throw an error if the vault timeout action is missing", async () => {
|
||||
// Arrange
|
||||
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = tokenService.setClientSecret(
|
||||
@@ -2138,9 +2131,7 @@ describe("TokenService", () => {
|
||||
describe("Memory storage tests", () => {
|
||||
it("sets the client secret in memory when there is an active user in global state", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await tokenService.setClientSecret(
|
||||
@@ -2176,9 +2167,7 @@ describe("TokenService", () => {
|
||||
describe("Disk storage tests", () => {
|
||||
it("sets the client secret on disk when there is an active user in global state", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await tokenService.setClientSecret(
|
||||
@@ -2222,9 +2211,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns null when no client secret is found in memory or disk", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientSecret();
|
||||
@@ -2237,17 +2224,15 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// set disk to undefined
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientSecret();
|
||||
@@ -2260,12 +2245,12 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// set disk to undefined
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientSecret(userIdFromAccessToken);
|
||||
@@ -2279,16 +2264,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientSecret();
|
||||
@@ -2300,11 +2283,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, undefined]);
|
||||
.nextState(undefined);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getClientSecret(userIdFromAccessToken);
|
||||
@@ -2327,11 +2310,11 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// Act
|
||||
await (tokenService as any).clearClientSecret(userIdFromAccessToken);
|
||||
@@ -2351,16 +2334,14 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, API_KEY_CLIENT_SECRET_DISK)
|
||||
.stateSubject.next([userIdFromAccessToken, clientSecret]);
|
||||
.nextState(clientSecret);
|
||||
|
||||
// Need to have global active id set to the user id
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await (tokenService as any).clearClientSecret();
|
||||
@@ -2634,7 +2615,7 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
const userId = "userId" as UserId;
|
||||
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).stateSubject.next(userId);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userId);
|
||||
|
||||
tokenService.clearAccessToken = jest.fn();
|
||||
(tokenService as any).clearRefreshToken = jest.fn();
|
||||
@@ -2693,7 +2674,7 @@ describe("TokenService", () => {
|
||||
|
||||
globalStateProvider
|
||||
.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL)
|
||||
.stateSubject.next(initialTwoFactorTokenRecord);
|
||||
.nextState(initialTwoFactorTokenRecord);
|
||||
|
||||
// Act
|
||||
await tokenService.setTwoFactorToken(email, twoFactorToken);
|
||||
@@ -2716,7 +2697,7 @@ describe("TokenService", () => {
|
||||
|
||||
globalStateProvider
|
||||
.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL)
|
||||
.stateSubject.next(initialTwoFactorTokenRecord);
|
||||
.nextState(initialTwoFactorTokenRecord);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getTwoFactorToken(email);
|
||||
@@ -2734,7 +2715,7 @@ describe("TokenService", () => {
|
||||
|
||||
globalStateProvider
|
||||
.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL)
|
||||
.stateSubject.next(initialTwoFactorTokenRecord);
|
||||
.nextState(initialTwoFactorTokenRecord);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getTwoFactorToken(email);
|
||||
@@ -2745,9 +2726,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns null when there is no two factor token record", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL)
|
||||
.stateSubject.next(null);
|
||||
globalStateProvider.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL).nextState(null);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getTwoFactorToken("testUser");
|
||||
@@ -2768,7 +2747,7 @@ describe("TokenService", () => {
|
||||
|
||||
globalStateProvider
|
||||
.getFake(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL)
|
||||
.stateSubject.next(initialTwoFactorTokenRecord);
|
||||
.nextState(initialTwoFactorTokenRecord);
|
||||
|
||||
// Act
|
||||
await tokenService.clearTwoFactorToken(email);
|
||||
@@ -2808,9 +2787,7 @@ describe("TokenService", () => {
|
||||
|
||||
it("sets the security stamp in memory when there is an active user in global state", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
// Act
|
||||
await tokenService.setSecurityStamp(mockSecurityStamp);
|
||||
@@ -2843,13 +2820,11 @@ describe("TokenService", () => {
|
||||
|
||||
it("returns the security stamp from memory when no user id is specified (uses global active user)", async () => {
|
||||
// Arrange
|
||||
globalStateProvider
|
||||
.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID)
|
||||
.stateSubject.next(userIdFromAccessToken);
|
||||
globalStateProvider.getFake(ACCOUNT_ACTIVE_ACCOUNT_ID).nextState(userIdFromAccessToken);
|
||||
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, SECURITY_STAMP_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, mockSecurityStamp]);
|
||||
.nextState(mockSecurityStamp);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getSecurityStamp();
|
||||
@@ -2862,7 +2837,7 @@ describe("TokenService", () => {
|
||||
// Arrange
|
||||
singleUserStateProvider
|
||||
.getFake(userIdFromAccessToken, SECURITY_STAMP_MEMORY)
|
||||
.stateSubject.next([userIdFromAccessToken, mockSecurityStamp]);
|
||||
.nextState(mockSecurityStamp);
|
||||
|
||||
// Act
|
||||
const result = await tokenService.getSecurityStamp(userIdFromAccessToken);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { KeyGenerationService } from "../../platform/abstractions/key-generation
|
||||
import { LogService } from "../../platform/abstractions/log.service";
|
||||
import { AbstractStorageService } from "../../platform/abstractions/storage.service";
|
||||
import { StorageLocation } from "../../platform/enums";
|
||||
import { Utils } from "../../platform/misc/utils";
|
||||
import { EncString, EncryptedString } from "../../platform/models/domain/enc-string";
|
||||
import { StorageOptions } from "../../platform/models/domain/storage-options";
|
||||
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
||||
@@ -875,8 +876,13 @@ export class TokenService implements TokenServiceAbstraction {
|
||||
// jwthelper methods
|
||||
// ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js
|
||||
|
||||
async decodeAccessToken(token?: string): Promise<DecodedAccessToken> {
|
||||
token = token ?? (await this.getAccessToken());
|
||||
async decodeAccessToken(tokenOrUserId?: string | UserId): Promise<DecodedAccessToken> {
|
||||
let token = tokenOrUserId as string;
|
||||
if (Utils.isGuid(tokenOrUserId)) {
|
||||
token = await this.getAccessToken(tokenOrUserId as UserId);
|
||||
} else {
|
||||
token ??= await this.getAccessToken();
|
||||
}
|
||||
|
||||
if (token == null) {
|
||||
throw new Error("Access token not found.");
|
||||
@@ -1012,10 +1018,10 @@ export class TokenService implements TokenServiceAbstraction {
|
||||
return decoded.iss;
|
||||
}
|
||||
|
||||
async getIsExternal(): Promise<boolean> {
|
||||
async getIsExternal(userId: UserId): Promise<boolean> {
|
||||
let decoded: DecodedAccessToken;
|
||||
try {
|
||||
decoded = await this.decodeAccessToken();
|
||||
decoded = await this.decodeAccessToken(userId);
|
||||
} catch (error) {
|
||||
throw new Error("Failed to decode access token: " + error.message);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user