1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-03-13 13:49:37 +01:00
This commit is contained in:
Jonathan Prusik 2025-02-10 17:43:59 -05:00
parent 03c24d2da2
commit 2ff54eb490
No known key found for this signature in database
GPG Key ID: 83CF2DF735A5EC35
7 changed files with 151 additions and 33 deletions

View File

@ -1,6 +1,6 @@
type InitContextMenuItems = Omit<chrome.contextMenus.CreateProperties, "contexts"> & {
checkPremiumAccess?: boolean;
checkUriIsBlocked?: boolean;
requiresPremiumAccess?: boolean;
requiresUnblockedUri?: boolean;
};
export { InitContextMenuItems };

View File

@ -16,7 +16,7 @@ export class CipherContextMenuHandler {
private cipherService: CipherService,
) {}
async update(url: string) {
async update(url: string, currentUriIsBlocked: boolean = false) {
if (this.mainContextMenuHandler.initRunning) {
return;
}
@ -76,6 +76,10 @@ export class CipherContextMenuHandler {
for (const cipher of ciphers) {
await this.updateForCipher(cipher);
}
if (currentUriIsBlocked) {
await this.mainContextMenuHandler.removeBlockedUriMenuItems();
}
}
private async updateForCipher(cipher: CipherView) {

View File

@ -41,7 +41,7 @@ export class MainContextMenuHandler {
id: AUTOFILL_ID,
parentId: ROOT_ID,
title: this.i18nService.t("autoFillLogin"),
checkUriIsBlocked: true,
requiresUnblockedUri: true,
},
{
id: COPY_USERNAME_ID,
@ -57,7 +57,7 @@ export class MainContextMenuHandler {
id: COPY_VERIFICATION_CODE_ID,
parentId: ROOT_ID,
title: this.i18nService.t("copyVerificationCode"),
checkPremiumAccess: true,
requiresPremiumAccess: true,
},
{
id: SEPARATOR_ID + 1,
@ -68,19 +68,19 @@ export class MainContextMenuHandler {
id: AUTOFILL_IDENTITY_ID,
parentId: ROOT_ID,
title: this.i18nService.t("autoFillIdentity"),
checkUriIsBlocked: true,
requiresUnblockedUri: true,
},
{
id: AUTOFILL_CARD_ID,
parentId: ROOT_ID,
title: this.i18nService.t("autoFillCard"),
checkUriIsBlocked: true,
requiresUnblockedUri: true,
},
{
id: SEPARATOR_ID + 2,
type: "separator",
parentId: ROOT_ID,
checkUriIsBlocked: true,
requiresUnblockedUri: true,
},
{
id: GENERATE_PASSWORD_ID,
@ -91,7 +91,7 @@ export class MainContextMenuHandler {
id: COPY_IDENTIFIER_ID,
parentId: ROOT_ID,
title: this.i18nService.t("copyElementIdentifier"),
checkUriIsBlocked: true,
requiresUnblockedUri: true,
},
];
private noCardsContextMenuItems: chrome.contextMenus.CreateProperties[] = [
@ -148,6 +148,44 @@ export class MainContextMenuHandler {
type: "separator",
},
];
// private currentPageBlockedContextMenuItems: chrome.contextMenus.CreateProperties[] = [
// {
// id: ROOT_ID,
// title: "Bitwarden",
// },
// // {
// // id: 'BLOCKED_URI_NOTICE',
// // parentId: ROOT_ID,
// // title: "Autofill is blocked for this website",
// // enabled: false,
// // // type: "separator",
// // },
// // {
// // id: SEPARATOR_ID + 1,
// // type: "separator",
// // parentId: ROOT_ID,
// // },
// {
// id: COPY_USERNAME_ID,
// parentId: ROOT_ID,
// title: this.i18nService.t("copyUsername"),
// },
// {
// id: COPY_PASSWORD_ID,
// parentId: ROOT_ID,
// title: this.i18nService.t("copyPassword"),
// },
// {
// id: SEPARATOR_ID + 1,
// type: "separator",
// parentId: ROOT_ID,
// },
// {
// id: GENERATE_PASSWORD_ID,
// parentId: ROOT_ID,
// title: this.i18nService.t("generatePasswordCopied"),
// },
// ];
constructor(
private stateService: StateService,
@ -162,7 +200,7 @@ export class MainContextMenuHandler {
*
* @returns a boolean showing whether or not items were created
*/
async init(currentUriIsBlocked?: boolean): Promise<boolean> {
async init(): Promise<boolean> {
const menuEnabled = await firstValueFrom(this.autofillSettingsService.enableContextMenu$);
if (!menuEnabled) {
await MainContextMenuHandler.removeAll();
@ -180,21 +218,23 @@ export class MainContextMenuHandler {
this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id),
);
for (const options of this.initContextMenuItems) {
if (options.checkPremiumAccess && !hasPremium) {
for (const {requiresPremiumAccess, requiresUnblockedUri, ...otherOptions} of this.initContextMenuItems) {
if (requiresPremiumAccess && !hasPremium) {
continue;
}
delete options.checkPremiumAccess;
// delete options.requiresPremiumAccess;
// delete options.requiresUnblockedUri;
if (options.checkUriIsBlocked && currentUriIsBlocked) {
continue;
}
delete options.checkUriIsBlocked;
await MainContextMenuHandler.create({ ...options, contexts: ["all"] });
await MainContextMenuHandler.create({ ...otherOptions, contexts: ["all"] });
}
// Don't need this check, because menu will be locked on init
// const currentUriIsBlocked = true;
// if (currentUriIsBlocked) {
// await this.removeBlockedUriMenuItems();
// }
} catch (error) {
this.logService.warning(error.message);
} finally {
@ -269,11 +309,12 @@ export class MainContextMenuHandler {
!cipher ||
(cipher.type === CipherType.Login && !Utils.isNullOrEmpty(cipher.login?.password))
) {
await createChildItem(AUTOFILL_ID);
// console.log('cipher?.viewPassword:', cipher?.viewPassword);
if (cipher?.viewPassword ?? true) {
await createChildItem(COPY_PASSWORD_ID);
}
await createChildItem(AUTOFILL_ID);
}
if (
@ -317,10 +358,31 @@ export class MainContextMenuHandler {
}
}
async removeBlockedUriMenuItems() {
try {
// await MainContextMenuHandler.removeAll();
// for (const menuItem of this.currentPageBlockedContextMenuItems) {
// await MainContextMenuHandler.create(menuItem);
// }
for (const menuItem of this.initContextMenuItems) {
// console.log('currentPageBlocked -> menuItem:', menuItem);
if (menuItem.requiresUnblockedUri && menuItem.id) {
await MainContextMenuHandler.remove(menuItem.id);
}
}
// await MainContextMenuHandler.create({ ...this.currentPageBlockedContextMenuItems, contexts: ["all"] });
} catch (error) {
this.logService.warning(error.message);
}
}
async noCards() {
try {
for (const option of this.noCardsContextMenuItems) {
await MainContextMenuHandler.create(option);
for (const menuItem of this.noCardsContextMenuItems) {
await MainContextMenuHandler.create(menuItem);
}
} catch (error) {
this.logService.warning(error.message);
@ -329,8 +391,8 @@ export class MainContextMenuHandler {
async noIdentities() {
try {
for (const option of this.noIdentitiesContextMenuItems) {
await MainContextMenuHandler.create(option);
for (const menuItem of this.noIdentitiesContextMenuItems) {
await MainContextMenuHandler.create(menuItem);
}
} catch (error) {
this.logService.warning(error.message);
@ -339,8 +401,8 @@ export class MainContextMenuHandler {
async noLogins() {
try {
for (const option of this.noLoginsContextMenuItems) {
await MainContextMenuHandler.create(option);
for (const menuItem of this.noLoginsContextMenuItems) {
await MainContextMenuHandler.create(menuItem);
}
await this.loadOptions(this.i18nService.t("addLoginMenu"), CREATE_LOGIN_ID);

View File

@ -450,6 +450,19 @@ export function getSubmitButtonKeywordsSet(element: HTMLElement): Set<string> {
return keywordsSet;
}
// export function urlIsOnDomainList(url, domainList: NeverDomain) {
// if (domainList && url?.length) {
// const tabURL = new URL(url);
// const tabIsBlocked = Object.keys(domainList).includes(tabURL.hostname);
// if (tabIsBlocked) {
// return true;
// }
// }
// return false;
// }
/**
* Generates the origin and subdomain match patterns for the URL.
*

View File

@ -1366,17 +1366,55 @@ export default class MainBackground {
await MainContextMenuHandler.removeAll();
if (forLocked) {
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(
map((a) => a?.id),
timeout({
first: 2000,
with: () => {
throw new Error("No active account found to logout");
},
}),
),
);
const accountStatus = await this.authService.getAuthStatus(activeUserId);
if (forLocked || accountStatus === AuthenticationStatus.Locked) {
await this.mainContextMenuHandler?.noAccess();
this.onUpdatedRan = this.onReplacedRan = false;
return;
}
await this.mainContextMenuHandler?.init();
const tab = await BrowserApi.getTabFromCurrentWindow();
const contextMenuIsEnabled = await this.mainContextMenuHandler?.init();
if (!contextMenuIsEnabled) {
this.onUpdatedRan = this.onReplacedRan = false;
return;
}
if (tab) {
await this.cipherContextMenuHandler?.update(tab.url);
const currentUriIsBlocked = await firstValueFrom(
this.domainSettingsService.blockedInteractionsUris$.pipe(
map((blockedInteractionsUris) => {
if (blockedInteractionsUris && tab?.url?.length) {
const tabURL = new URL(tab.url);
const tabIsBlocked = Object.keys(blockedInteractionsUris).includes(tabURL.hostname);
if (tabIsBlocked) {
return true;
}
}
return false;
})
));
// if (currentUriIsBlocked) {
// await this.mainContextMenuHandler?.removeBlockedUriMenuItems();
// }
await this.cipherContextMenuHandler?.update(tab.url, currentUriIsBlocked);
this.onUpdatedRan = this.onReplacedRan = false;
}
}

View File

@ -247,6 +247,7 @@ export abstract class BrowserPlatformUtilsService implements PlatformUtilsServic
* @param options - Options for the clipboard operation.
*/
copyToClipboard(text: string, options?: ClipboardOptions): void {
console.log('copyToClipboard text:', text);
const windowContext = options?.window || (this.globalContext as Window);
const clearing = Boolean(options?.clearing);
const clearMs: number = options?.clearMs || null;

View File

@ -73,7 +73,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.LimitItemDeletion]: FALSE,
/* Autofill */
[FeatureFlag.BlockBrowserInjectionsByDomain]: FALSE,
[FeatureFlag.BlockBrowserInjectionsByDomain]: true,
[FeatureFlag.DelayFido2PageScriptInitWithinMv2]: FALSE,
[FeatureFlag.EnableNewCardCombinedExpiryAutofill]: FALSE,
[FeatureFlag.GenerateIdentityFillScriptRefactor]: FALSE,