1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 00:03:56 +00:00

fix(recovery-code-login): [PM-18474] Fix for Recovery Code Login (#13497)

* fix(recovery-code-login): [PM-18474] Fix for Recovery Code Login - Fixed the recovery code login to work with the new device verification notice flow.

* test(recovery-code-login): [PM-18474] Fix for Recovery Code Login - Tests added.
This commit is contained in:
Patrick-Pimentel-Bitwarden
2025-02-20 16:45:19 -05:00
committed by GitHub
parent 657902cdcc
commit 598139d739
6 changed files with 210 additions and 27 deletions

View File

@@ -14,6 +14,7 @@ import {
NewDeviceVerificationNoticeService,
NewDeviceVerificationNotice,
NEW_DEVICE_VERIFICATION_NOTICE_KEY,
SKIP_NEW_DEVICE_VERIFICATION_NOTICE,
} from "./new-device-verification-notice.service";
describe("New Device Verification Notice", () => {
@@ -21,6 +22,7 @@ describe("New Device Verification Notice", () => {
const userId = Utils.newGuid() as UserId;
let newDeviceVerificationService: NewDeviceVerificationNoticeService;
let mockNoticeState: FakeSingleUserState<NewDeviceVerificationNotice>;
let mockSkipState: FakeSingleUserState<boolean>;
let stateProvider: FakeStateProvider;
let accountService: FakeAccountService;
@@ -28,6 +30,7 @@ describe("New Device Verification Notice", () => {
accountService = mockAccountServiceWith(userId);
stateProvider = new FakeStateProvider(accountService);
mockNoticeState = stateProvider.singleUser.getFake(userId, NEW_DEVICE_VERIFICATION_NOTICE_KEY);
mockSkipState = stateProvider.singleUser.getFake(userId, SKIP_NEW_DEVICE_VERIFICATION_NOTICE);
newDeviceVerificationService = new NewDeviceVerificationNoticeService(stateProvider);
});
@@ -82,4 +85,28 @@ describe("New Device Verification Notice", () => {
expect(result).toEqual(newState);
});
});
describe("skipNotice state", () => {
it("emits skip notice state", async () => {
const shouldSkip = true;
await stateProvider.setUserState(SKIP_NEW_DEVICE_VERIFICATION_NOTICE, shouldSkip, userId);
const result = await firstValueFrom(newDeviceVerificationService.skipState$(userId));
expect(result).toBe(shouldSkip);
});
it("should update the skip notice state", async () => {
const initialSkipState = false;
const updatedSkipState = true;
mockSkipState.nextState(initialSkipState);
await newDeviceVerificationService.updateNewDeviceVerificationSkipNoticeState(
userId,
updatedSkipState,
);
const result = await firstValueFrom(newDeviceVerificationService.skipState$(userId));
expect(result).toBe(updatedSkipState);
});
});
});

View File

@@ -42,6 +42,15 @@ export const NEW_DEVICE_VERIFICATION_NOTICE_KEY =
},
);
export const SKIP_NEW_DEVICE_VERIFICATION_NOTICE = new UserKeyDefinition<boolean>(
NEW_DEVICE_VERIFICATION_NOTICE,
"shouldSkip",
{
deserializer: (data: boolean) => data,
clearOn: ["logout"],
},
);
@Injectable()
export class NewDeviceVerificationNoticeService {
constructor(private stateProvider: StateProvider) {}
@@ -62,4 +71,19 @@ export class NewDeviceVerificationNoticeService {
return { ...newState };
});
}
private skipState(userId: UserId): SingleUserState<boolean> {
return this.stateProvider.getUser(userId, SKIP_NEW_DEVICE_VERIFICATION_NOTICE);
}
skipState$(userId: UserId): Observable<boolean | null> {
return this.skipState(userId).state$;
}
async updateNewDeviceVerificationSkipNoticeState(
userId: UserId,
shouldSkip: boolean,
): Promise<void> {
await this.skipState(userId).update(() => shouldSkip);
}
}