mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
Auth/PM-5263 - TokenService State provider migration bug fix to avoid persisting tokens in local storage (#8413)
* PM-5263 - Update token svc state provider migration to avoid persisting secrets that shouldn't exist in local storage to state provider local storage using new migration helper type. * PM-5263 - TokenSvc migration - tests TODO * write tests for migration * fix tests --------- Co-authored-by: Jake Fink <jfink@bitwarden.com>
This commit is contained in:
parent
0957b54d03
commit
899172722a
@ -124,65 +124,107 @@ describe("TokenServiceStateProviderMigrator", () => {
|
|||||||
sut = new TokenServiceStateProviderMigrator(37, 38);
|
sut = new TokenServiceStateProviderMigrator(37, 38);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should remove state service data from all accounts that have it", async () => {
|
describe("Session storage", () => {
|
||||||
await sut.migrate(helper);
|
it("should remove state service data from all accounts that have it", async () => {
|
||||||
|
await sut.migrate(helper);
|
||||||
|
|
||||||
expect(helper.set).toHaveBeenCalledWith("user1", {
|
expect(helper.set).toHaveBeenCalledWith("user1", {
|
||||||
tokens: {
|
tokens: {
|
||||||
otherStuff: "overStuff2",
|
otherStuff: "overStuff2",
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
email: "user1Email",
|
email: "user1Email",
|
||||||
otherStuff: "overStuff3",
|
otherStuff: "overStuff3",
|
||||||
},
|
},
|
||||||
keys: {
|
keys: {
|
||||||
otherStuff: "overStuff4",
|
otherStuff: "overStuff4",
|
||||||
},
|
},
|
||||||
otherStuff: "otherStuff5",
|
otherStuff: "otherStuff5",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(helper.set).toHaveBeenCalledTimes(2);
|
||||||
|
expect(helper.set).not.toHaveBeenCalledWith("user2", any());
|
||||||
|
expect(helper.set).not.toHaveBeenCalledWith("user3", any());
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(helper.set).toHaveBeenCalledTimes(2);
|
it("should migrate data to state providers for defined accounts that have the data", async () => {
|
||||||
expect(helper.set).not.toHaveBeenCalledWith("user2", any());
|
await sut.migrate(helper);
|
||||||
expect(helper.set).not.toHaveBeenCalledWith("user3", any());
|
|
||||||
|
// Two factor Token Migration
|
||||||
|
expect(helper.setToGlobal).toHaveBeenLastCalledWith(
|
||||||
|
EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL,
|
||||||
|
{
|
||||||
|
user1Email: "twoFactorToken",
|
||||||
|
user2Email: "twoFactorToken",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(helper.setToGlobal).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(helper.setToUser).toHaveBeenCalledWith("user1", ACCESS_TOKEN_DISK, "accessToken");
|
||||||
|
expect(helper.setToUser).toHaveBeenCalledWith("user1", REFRESH_TOKEN_DISK, "refreshToken");
|
||||||
|
expect(helper.setToUser).toHaveBeenCalledWith(
|
||||||
|
"user1",
|
||||||
|
API_KEY_CLIENT_ID_DISK,
|
||||||
|
"apiKeyClientId",
|
||||||
|
);
|
||||||
|
expect(helper.setToUser).toHaveBeenCalledWith(
|
||||||
|
"user1",
|
||||||
|
API_KEY_CLIENT_SECRET_DISK,
|
||||||
|
"apiKeyClientSecret",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", ACCESS_TOKEN_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", REFRESH_TOKEN_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", API_KEY_CLIENT_ID_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith(
|
||||||
|
"user2",
|
||||||
|
API_KEY_CLIENT_SECRET_DISK,
|
||||||
|
any(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Expect that we didn't migrate anything to user 3
|
||||||
|
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", ACCESS_TOKEN_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", REFRESH_TOKEN_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", API_KEY_CLIENT_ID_DISK, any());
|
||||||
|
expect(helper.setToUser).not.toHaveBeenCalledWith(
|
||||||
|
"user3",
|
||||||
|
API_KEY_CLIENT_SECRET_DISK,
|
||||||
|
any(),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
describe("Local storage", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
helper = mockMigrationHelper(preMigrationJson(), 37, "web-disk-local");
|
||||||
|
});
|
||||||
|
it("should remove state service data from all accounts that have it", async () => {
|
||||||
|
await sut.migrate(helper);
|
||||||
|
|
||||||
it("should migrate data to state providers for defined accounts that have the data", async () => {
|
expect(helper.set).toHaveBeenCalledWith("user1", {
|
||||||
await sut.migrate(helper);
|
tokens: {
|
||||||
|
otherStuff: "overStuff2",
|
||||||
|
},
|
||||||
|
profile: {
|
||||||
|
email: "user1Email",
|
||||||
|
otherStuff: "overStuff3",
|
||||||
|
},
|
||||||
|
keys: {
|
||||||
|
otherStuff: "overStuff4",
|
||||||
|
},
|
||||||
|
otherStuff: "otherStuff5",
|
||||||
|
});
|
||||||
|
|
||||||
// Two factor Token Migration
|
expect(helper.set).toHaveBeenCalledTimes(2);
|
||||||
expect(helper.setToGlobal).toHaveBeenLastCalledWith(
|
expect(helper.set).not.toHaveBeenCalledWith("user2", any());
|
||||||
EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL,
|
expect(helper.set).not.toHaveBeenCalledWith("user3", any());
|
||||||
{
|
});
|
||||||
user1Email: "twoFactorToken",
|
|
||||||
user2Email: "twoFactorToken",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
expect(helper.setToGlobal).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
expect(helper.setToUser).toHaveBeenCalledWith("user1", ACCESS_TOKEN_DISK, "accessToken");
|
it("should not migrate any data to local storage", async () => {
|
||||||
expect(helper.setToUser).toHaveBeenCalledWith("user1", REFRESH_TOKEN_DISK, "refreshToken");
|
await sut.migrate(helper);
|
||||||
expect(helper.setToUser).toHaveBeenCalledWith(
|
|
||||||
"user1",
|
|
||||||
API_KEY_CLIENT_ID_DISK,
|
|
||||||
"apiKeyClientId",
|
|
||||||
);
|
|
||||||
expect(helper.setToUser).toHaveBeenCalledWith(
|
|
||||||
"user1",
|
|
||||||
API_KEY_CLIENT_SECRET_DISK,
|
|
||||||
"apiKeyClientSecret",
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", ACCESS_TOKEN_DISK, any());
|
expect(helper.setToUser).not.toHaveBeenCalled();
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", REFRESH_TOKEN_DISK, any());
|
});
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", API_KEY_CLIENT_ID_DISK, any());
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user2", API_KEY_CLIENT_SECRET_DISK, any());
|
|
||||||
|
|
||||||
// Expect that we didn't migrate anything to user 3
|
|
||||||
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", ACCESS_TOKEN_DISK, any());
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", REFRESH_TOKEN_DISK, any());
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", API_KEY_CLIENT_ID_DISK, any());
|
|
||||||
expect(helper.setToUser).not.toHaveBeenCalledWith("user3", API_KEY_CLIENT_SECRET_DISK, any());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -84,7 +84,10 @@ export class TokenServiceStateProviderMigrator extends Migrator<37, 38> {
|
|||||||
|
|
||||||
if (existingAccessToken != null) {
|
if (existingAccessToken != null) {
|
||||||
// Only migrate data that exists
|
// Only migrate data that exists
|
||||||
await helper.setToUser(userId, ACCESS_TOKEN_DISK, existingAccessToken);
|
if (helper.type !== "web-disk-local") {
|
||||||
|
// only migrate access token to session storage - never local.
|
||||||
|
await helper.setToUser(userId, ACCESS_TOKEN_DISK, existingAccessToken);
|
||||||
|
}
|
||||||
delete account.tokens.accessToken;
|
delete account.tokens.accessToken;
|
||||||
updatedAccount = true;
|
updatedAccount = true;
|
||||||
}
|
}
|
||||||
@ -93,7 +96,10 @@ export class TokenServiceStateProviderMigrator extends Migrator<37, 38> {
|
|||||||
const existingRefreshToken = account?.tokens?.refreshToken;
|
const existingRefreshToken = account?.tokens?.refreshToken;
|
||||||
|
|
||||||
if (existingRefreshToken != null) {
|
if (existingRefreshToken != null) {
|
||||||
await helper.setToUser(userId, REFRESH_TOKEN_DISK, existingRefreshToken);
|
if (helper.type !== "web-disk-local") {
|
||||||
|
// only migrate refresh token to session storage - never local.
|
||||||
|
await helper.setToUser(userId, REFRESH_TOKEN_DISK, existingRefreshToken);
|
||||||
|
}
|
||||||
delete account.tokens.refreshToken;
|
delete account.tokens.refreshToken;
|
||||||
updatedAccount = true;
|
updatedAccount = true;
|
||||||
}
|
}
|
||||||
@ -102,7 +108,10 @@ export class TokenServiceStateProviderMigrator extends Migrator<37, 38> {
|
|||||||
const existingApiKeyClientId = account?.profile?.apiKeyClientId;
|
const existingApiKeyClientId = account?.profile?.apiKeyClientId;
|
||||||
|
|
||||||
if (existingApiKeyClientId != null) {
|
if (existingApiKeyClientId != null) {
|
||||||
await helper.setToUser(userId, API_KEY_CLIENT_ID_DISK, existingApiKeyClientId);
|
if (helper.type !== "web-disk-local") {
|
||||||
|
// only migrate client id to session storage - never local.
|
||||||
|
await helper.setToUser(userId, API_KEY_CLIENT_ID_DISK, existingApiKeyClientId);
|
||||||
|
}
|
||||||
delete account.profile.apiKeyClientId;
|
delete account.profile.apiKeyClientId;
|
||||||
updatedAccount = true;
|
updatedAccount = true;
|
||||||
}
|
}
|
||||||
@ -110,7 +119,10 @@ export class TokenServiceStateProviderMigrator extends Migrator<37, 38> {
|
|||||||
// Migrate API key client secret
|
// Migrate API key client secret
|
||||||
const existingApiKeyClientSecret = account?.keys?.apiKeyClientSecret;
|
const existingApiKeyClientSecret = account?.keys?.apiKeyClientSecret;
|
||||||
if (existingApiKeyClientSecret != null) {
|
if (existingApiKeyClientSecret != null) {
|
||||||
await helper.setToUser(userId, API_KEY_CLIENT_SECRET_DISK, existingApiKeyClientSecret);
|
if (helper.type !== "web-disk-local") {
|
||||||
|
// only migrate client secret to session storage - never local.
|
||||||
|
await helper.setToUser(userId, API_KEY_CLIENT_SECRET_DISK, existingApiKeyClientSecret);
|
||||||
|
}
|
||||||
delete account.keys.apiKeyClientSecret;
|
delete account.keys.apiKeyClientSecret;
|
||||||
updatedAccount = true;
|
updatedAccount = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user