bitwarden-estensione-browser/apps/browser/src/browser/browserApi.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

237 lines
6.5 KiB
TypeScript
Raw Normal View History

2022-06-14 17:10:53 +02:00
import { Utils } from "@bitwarden/common/misc/utils";
2022-02-24 18:14:04 +01:00
import { SafariApp } from "./safariApp";
2018-01-20 20:05:20 +01:00
export class BrowserApi {
static isWebExtensionsApi: boolean = typeof browser !== "undefined";
static isSafariApi: boolean =
navigator.userAgent.indexOf(" Safari/") !== -1 &&
navigator.userAgent.indexOf(" Chrome/") === -1 &&
navigator.userAgent.indexOf(" Chromium/") === -1;
2018-01-16 03:59:25 +01:00
static isChromeApi: boolean = !BrowserApi.isSafariApi && typeof chrome !== "undefined";
2018-08-15 03:29:32 +02:00
static isFirefoxOnAndroid: boolean =
navigator.userAgent.indexOf("Firefox/") !== -1 && navigator.userAgent.indexOf("Android") !== -1;
2021-12-21 15:43:35 +01:00
static async getTabFromCurrentWindowId(): Promise<chrome.tabs.Tab> | null {
return await BrowserApi.tabsQueryFirst({
2018-03-04 04:48:38 +01:00
active: true,
windowId: chrome.windows.WINDOW_ID_CURRENT,
});
}
2021-12-21 15:43:35 +01:00
static async getTabFromCurrentWindow(): Promise<chrome.tabs.Tab> | null {
return await BrowserApi.tabsQueryFirst({
active: true,
currentWindow: true,
2021-12-21 15:43:35 +01:00
});
}
static async getActiveTabs(): Promise<chrome.tabs.Tab[]> {
return await BrowserApi.tabsQuery({
active: true,
2017-12-07 21:36:24 +01:00
});
}
2021-12-21 15:43:35 +01:00
2019-08-20 19:54:10 +02:00
static async tabsQuery(options: chrome.tabs.QueryInfo): Promise<chrome.tabs.Tab[]> {
return new Promise((resolve) => {
chrome.tabs.query(options, (tabs: any[]) => {
resolve(tabs);
2021-12-21 15:43:35 +01:00
});
});
2018-01-12 17:09:30 +01:00
}
2021-12-21 15:43:35 +01:00
2021-10-18 16:34:14 +02:00
static async tabsQueryFirst(options: chrome.tabs.QueryInfo): Promise<chrome.tabs.Tab> | null {
const tabs = await BrowserApi.tabsQuery(options);
if (tabs.length > 0) {
return tabs[0];
2021-12-21 15:43:35 +01:00
}
return null;
}
2021-12-21 15:43:35 +01:00
static tabSendMessageData(
tab: chrome.tabs.Tab,
2018-01-15 16:01:25 +01:00
command: string,
data: any = null
): Promise<any[]> {
const obj: any = {
2017-12-07 21:36:24 +01:00
command: command,
2021-12-21 15:43:35 +01:00
};
if (data != null) {
obj.data = data;
}
2021-12-21 15:43:35 +01:00
2019-08-22 02:45:23 +02:00
return BrowserApi.tabSendMessage(tab, obj);
2018-01-15 17:04:28 +01:00
}
2021-12-21 15:43:35 +01:00
2018-04-11 20:52:49 +02:00
static async tabSendMessage(
tab: chrome.tabs.Tab,
obj: any,
options: chrome.tabs.MessageSendOptions = null
): Promise<any> {
if (!tab || !tab.id) {
2019-03-05 21:05:04 +01:00
return;
}
2021-12-21 15:43:35 +01:00
2019-03-05 21:05:04 +01:00
return new Promise<void>((resolve) => {
chrome.tabs.sendMessage(tab.id, obj, options, () => {
if (chrome.runtime.lastError) {
// Some error happened
}
resolve();
2021-12-21 15:43:35 +01:00
});
});
}
static async getPrivateModeWindows(): Promise<browser.windows.Window[]> {
return (await browser.windows.getAll()).filter((win) => win.incognito);
}
static async onWindowCreated(callback: (win: chrome.windows.Window) => any) {
return chrome.windows.onCreated.addListener(callback);
}
2021-12-21 15:43:35 +01:00
static getBackgroundPage(): any {
return chrome.extension.getBackgroundPage();
2021-12-21 15:43:35 +01:00
}
static getApplicationVersion(): string {
return chrome.runtime.getManifest().version;
2021-12-21 15:43:35 +01:00
}
static async isPopupOpen(): Promise<boolean> {
return Promise.resolve(chrome.extension.getViews({ type: "popup" }).length > 0);
2021-12-21 15:43:35 +01:00
}
2022-02-24 18:14:04 +01:00
static createNewTab(url: string, extensionPage = false, active = true) {
chrome.tabs.create({ url: url, active: active });
2021-12-21 15:43:35 +01:00
}
2021-10-18 16:34:14 +02:00
static messageListener(
name: string,
callback: (message: any, sender: chrome.runtime.MessageSender, response: any) => void
2021-12-21 15:43:35 +01:00
) {
2021-10-18 16:34:14 +02:00
chrome.runtime.onMessage.addListener(
(msg: any, sender: chrome.runtime.MessageSender, response: any) => {
callback(msg, sender, response);
2021-12-21 15:43:35 +01:00
}
);
}
static async closeLoginTab() {
const tabs = await BrowserApi.tabsQuery({
active: true,
title: "Bitwarden",
windowType: "normal",
currentWindow: true,
2021-12-21 15:43:35 +01:00
});
if (tabs.length === 0) {
2021-12-21 15:43:35 +01:00
return;
}
const tabToClose = tabs[tabs.length - 1].id;
chrome.tabs.remove(tabToClose);
2021-12-21 15:43:35 +01:00
}
static async focusSpecifiedTab(tabId: number) {
chrome.tabs.update(tabId, { active: true, highlighted: true });
2021-12-21 15:43:35 +01:00
}
static closePopup(win: Window) {
if (BrowserApi.isWebExtensionsApi && BrowserApi.isFirefoxOnAndroid) {
// Reactivating the active tab dismisses the popup tab. The promise final
// condition is only called if the popup wasn't already dismissed (future proofing).
2018-08-15 03:32:13 +02:00
// ref: https://bugzilla.mozilla.org/show_bug.cgi?id=1433604
browser.tabs.update({ active: true }).finally(win.close);
2021-12-21 15:43:35 +01:00
} else {
2018-01-12 22:42:47 +01:00
win.close();
2021-12-21 15:43:35 +01:00
}
}
2018-01-15 16:01:25 +01:00
static downloadFile(win: Window, blobData: any, blobOptions: any, fileName: string) {
if (BrowserApi.isSafariApi) {
const type = blobOptions != null ? blobOptions.type : null;
let data: string = null;
if (type === "text/plain" && typeof blobData === "string") {
data = blobData;
2021-12-21 15:43:35 +01:00
} else {
data = Utils.fromBufferToB64(blobData);
2021-12-21 15:43:35 +01:00
}
2019-08-22 02:45:23 +02:00
SafariApp.sendMessageToApp(
2018-01-15 16:01:25 +01:00
"downloadFile",
2019-08-22 02:45:23 +02:00
JSON.stringify({
2019-08-23 15:55:59 +02:00
blobData: data,
blobOptions: blobOptions,
fileName: fileName,
2021-12-21 15:43:35 +01:00
}),
true
);
} else {
2018-01-15 16:01:25 +01:00
const blob = new Blob([blobData], blobOptions);
2018-01-15 17:04:28 +01:00
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
2021-12-21 15:43:35 +01:00
} else {
const a = win.document.createElement("a");
a.href = URL.createObjectURL(blob);
2018-01-15 17:04:28 +01:00
a.download = fileName;
win.document.body.appendChild(a);
a.click();
win.document.body.removeChild(a);
2021-12-21 15:43:35 +01:00
}
}
}
2018-01-26 16:48:32 +01:00
static gaFilter() {
return process.env.ENV !== "production";
2021-12-21 15:43:35 +01:00
}
2018-04-11 20:52:49 +02:00
static getUILanguage(win: Window) {
return chrome.i18n.getUILanguage();
2021-12-21 15:43:35 +01:00
}
static reloadExtension(win: Window) {
2017-12-07 21:36:24 +01:00
if (win != null) {
return win.location.reload(true);
} else {
return chrome.runtime.reload();
2021-12-21 15:43:35 +01:00
}
}
static reloadOpenWindows() {
const views = chrome.extension.getViews() as Window[];
2021-12-21 15:43:35 +01:00
views
.filter((w) => w.location.href != null)
.forEach((w) => {
w.location.reload();
2021-12-21 15:43:35 +01:00
});
}
static connectNative(application: string): browser.runtime.Port | chrome.runtime.Port {
if (BrowserApi.isWebExtensionsApi) {
return browser.runtime.connectNative(application);
} else if (BrowserApi.isChromeApi) {
return chrome.runtime.connectNative(application);
2021-12-21 15:43:35 +01:00
}
}
static requestPermission(permission: any) {
if (BrowserApi.isWebExtensionsApi) {
return browser.permissions.request(permission);
2021-12-21 15:43:35 +01:00
}
2021-02-10 16:40:15 +01:00
return new Promise((resolve, reject) => {
chrome.permissions.request(permission, resolve);
});
}
2021-12-21 15:43:35 +01:00
static getPlatformInfo(): Promise<browser.runtime.PlatformInfo | chrome.runtime.PlatformInfo> {
if (BrowserApi.isWebExtensionsApi) {
return browser.runtime.getPlatformInfo();
}
return new Promise((resolve) => {
chrome.runtime.getPlatformInfo(resolve);
});
}
}