bitwarden-estensione-browser/apps/web/src/services/webPlatformUtils.service.ts

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

255 lines
7.3 KiB
TypeScript
Raw Normal View History

import { Injectable } from "@angular/core";
import Swal, { SweetAlertIcon } from "sweetalert2";
2018-06-08 20:56:26 +02:00
2022-06-14 17:10:53 +02:00
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { ClientType } from "@bitwarden/common/enums/clientType";
import { DeviceType } from "@bitwarden/common/enums/deviceType";
2018-06-05 21:02:53 +02:00
@Injectable()
2018-06-05 21:02:53 +02:00
export class WebPlatformUtilsService implements PlatformUtilsService {
2018-07-09 15:32:24 +02:00
private browserCache: DeviceType = null;
2018-06-05 21:02:53 +02:00
constructor(
private i18nService: I18nService,
private messagingService: MessagingService,
private logService: LogService
[Account Switching] [Refactor] Implement new account centric services (#1220) * [chore] updated services.module to use account services * [refactor] sorted services provided by services.module * [chore] removed references to deleted jslib services * [chore] used activeAccount over storageService for account level storage items * [chore] resolved linter warnings * Refactor activeAccountService to stateService * [bug] Remove uneeded calls to state service on logout This was causing console erros on logout. Clearing of data is handled fully in dedicated services, clearing them in state afterwards is essentially a redundant call. * [bug] Add back null locked callback to VaultTimeoutService * Move call to get showUpdateKey * [bug] Ensure HtmlStorageService does not override StateService options and locations * [bug] Adjust theme logic to pull from the new storage locations * [bug] Correct theme not sticking on refresh * [bug] Add enableFullWidth to the account model * [bug] fix theme option empty when light is selected * [bug] init state on application start * [bug] Reinit state when coming back from a lock * [style] Fix lint complaints * [bug] Clean state on logout * [chore] Resolved merge issues * [bug] Correct default for enableGravitars * Bump angular to 12. * Remove angular.json * Bump rxjs * Fix build errors, remove file-loader with asset/resource * Use contenthash * Bump jslib * Bump ngx-toastr * [chore] resolve issues from merge * [chore] resolve issues from merge * [bug] Add missing bracket * Use newer import syntax * [bug] Correct service orge * [style] Fix lint complaints * [chore] update jslib * [review] Address code review * [review] Address code review * [review] Rename providerService to webProviderService Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com> Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-12-14 17:10:26 +01:00
) {}
2018-06-05 21:02:53 +02:00
getDevice(): DeviceType {
2018-07-09 15:32:24 +02:00
if (this.browserCache != null) {
return this.browserCache;
2018-06-05 21:02:53 +02:00
}
2021-12-17 15:57:11 +01:00
if (
2018-07-09 15:32:24 +02:00
navigator.userAgent.indexOf(" Firefox/") !== -1 ||
2018-06-05 21:02:53 +02:00
navigator.userAgent.indexOf(" Gecko/") !== -1
2021-12-17 15:57:11 +01:00
) {
2018-06-05 21:02:53 +02:00
this.browserCache = DeviceType.FirefoxBrowser;
} else if (navigator.userAgent.indexOf(" OPR/") >= 0) {
2018-07-09 15:32:24 +02:00
this.browserCache = DeviceType.OperaBrowser;
} else if (navigator.userAgent.indexOf(" Edg/") !== -1) {
this.browserCache = DeviceType.EdgeBrowser;
} else if (navigator.userAgent.indexOf(" Vivaldi/") !== -1) {
this.browserCache = DeviceType.VivaldiBrowser;
} else if (
navigator.userAgent.indexOf(" Safari/") !== -1 &&
navigator.userAgent.indexOf("Chrome") === -1
2021-12-17 15:57:11 +01:00
) {
2018-07-09 15:32:24 +02:00
this.browserCache = DeviceType.SafariBrowser;
} else if ((window as any).chrome && navigator.userAgent.indexOf(" Chrome/") !== -1) {
this.browserCache = DeviceType.ChromeBrowser;
} else if (navigator.userAgent.indexOf(" Trident/") !== -1) {
this.browserCache = DeviceType.IEBrowser;
2021-12-17 15:57:11 +01:00
} else {
2018-07-09 15:32:24 +02:00
this.browserCache = DeviceType.UnknownBrowser;
2018-06-05 21:02:53 +02:00
}
2018-07-09 15:32:24 +02:00
return this.browserCache;
2018-06-05 21:02:53 +02:00
}
getDeviceString(): string {
2018-07-09 15:32:24 +02:00
const device = DeviceType[this.getDevice()].toLowerCase();
return device.replace("browser", "");
2018-06-05 21:02:53 +02:00
}
2022-02-08 13:22:31 +01:00
getClientType() {
return ClientType.Web;
}
2018-06-05 21:02:53 +02:00
isFirefox(): boolean {
2018-07-09 15:32:24 +02:00
return this.getDevice() === DeviceType.FirefoxBrowser;
2018-06-06 15:43:28 +02:00
}
2018-06-05 21:02:53 +02:00
isChrome(): boolean {
2018-07-09 15:32:24 +02:00
return this.getDevice() === DeviceType.ChromeBrowser;
2018-06-05 21:02:53 +02:00
}
isEdge(): boolean {
2018-07-09 15:32:24 +02:00
return this.getDevice() === DeviceType.EdgeBrowser;
2018-06-05 21:02:53 +02:00
}
isOpera(): boolean {
2018-07-09 15:32:24 +02:00
return this.getDevice() === DeviceType.OperaBrowser;
2018-06-07 23:12:11 +02:00
}
isVivaldi(): boolean {
2018-07-09 15:32:24 +02:00
return this.getDevice() === DeviceType.VivaldiBrowser;
2018-06-05 21:02:53 +02:00
}
isSafari(): boolean {
return this.getDevice() === DeviceType.SafariBrowser;
}
isMacAppStore(): boolean {
2018-06-07 23:12:11 +02:00
return false;
2018-06-05 21:02:53 +02:00
}
isViewOpen(): Promise<boolean> {
2018-06-08 18:23:46 +02:00
return Promise.resolve(false);
}
2018-06-05 21:02:53 +02:00
2021-04-07 20:42:57 +02:00
launchUri(uri: string, options?: any): void {
const a = document.createElement("a");
a.href = uri;
if (options == null || !options.sameWindow) {
a.target = "_blank";
a.rel = "noreferrer noopener";
2018-06-05 21:02:53 +02:00
}
a.classList.add("d-none");
2021-03-16 17:44:31 +01:00
document.body.appendChild(a);
2018-06-07 23:12:11 +02:00
a.click();
document.body.removeChild(a);
2021-12-17 15:57:11 +01:00
}
getApplicationVersion(): Promise<string> {
return Promise.resolve(process.env.APPLICATION_VERSION || "-");
2021-12-17 15:57:11 +01:00
}
supportsWebAuthn(win: Window): boolean {
2018-06-05 21:02:53 +02:00
return typeof PublicKeyCredential !== "undefined";
2021-12-17 15:57:11 +01:00
}
2018-06-05 21:02:53 +02:00
supportsDuo(): boolean {
return true;
2021-12-17 15:57:11 +01:00
}
showToast(
2018-06-05 21:02:53 +02:00
type: "error" | "success" | "warning" | "info",
title: string,
text: string | string[],
options?: any
): void {
this.messagingService.send("showToast", {
text: text,
title: title,
type: type,
options: options,
});
2021-12-17 15:57:11 +01:00
}
async showDialog(
body: string,
title?: string,
2018-06-05 21:02:53 +02:00
confirmText?: string,
cancelText?: string,
type?: string,
2022-02-24 12:10:07 +01:00
bodyIsHtml = false
2021-12-17 15:57:11 +01:00
) {
2018-07-26 04:01:26 +02:00
let iconClasses: string = null;
if (type != null) {
// If you add custom types to this part, the type to SweetAlertIcon cast below needs to be changed.
switch (type) {
case "success":
iconClasses = "bwi-check text-success";
break;
case "warning":
iconClasses = "bwi-exclamation-triangle text-warning";
2021-12-17 15:57:11 +01:00
break;
2018-06-05 21:02:53 +02:00
case "error":
iconClasses = "bwi-error text-danger";
2018-07-26 04:01:26 +02:00
break;
case "info":
iconClasses = "bwi-info-circle text-info";
2018-07-26 04:01:26 +02:00
break;
2021-12-17 15:57:11 +01:00
default:
break;
2018-06-05 21:02:53 +02:00
}
}
2019-02-27 04:42:30 +01:00
const bootstrapModal = document.querySelector("div.modal");
if (bootstrapModal != null) {
bootstrapModal.removeAttribute("tabindex");
}
const iconHtmlStr =
iconClasses != null ? `<i class="swal-custom-icon bwi ${iconClasses}"></i>` : undefined;
const confirmed = await Swal.fire({
heightAuto: false,
buttonsStyling: false,
icon: type as SweetAlertIcon, // required to be any of the SweetAlertIcons to output the iconHtml.
iconHtml: iconHtmlStr,
text: bodyIsHtml ? null : body,
html: bodyIsHtml ? body : null,
2021-05-13 16:08:16 +02:00
titleText: title,
showCancelButton: cancelText != null,
cancelButtonText: cancelText,
showConfirmButton: true,
confirmButtonText: confirmText == null ? this.i18nService.t("ok") : confirmText,
});
2021-12-17 15:57:11 +01:00
if (bootstrapModal != null) {
bootstrapModal.setAttribute("tabindex", "-1");
}
return confirmed.value;
2021-12-17 15:57:11 +01:00
}
isDev(): boolean {
return process.env.NODE_ENV === "development";
2021-12-17 15:57:11 +01:00
}
isSelfHost(): boolean {
return process.env.ENV.toString() === "selfhosted";
2021-12-17 15:57:11 +01:00
}
copyToClipboard(text: string, options?: any): void | boolean {
2018-08-17 18:25:21 +02:00
let win = window;
let doc = window.document;
if (options && (options.window || options.win)) {
win = options.window || options.win;
doc = win.document;
} else if (options && options.doc) {
2018-08-17 18:25:21 +02:00
doc = options.doc;
}
2018-08-20 15:20:24 +02:00
if ((win as any).clipboardData && (win as any).clipboardData.setData) {
// IE specific code path to prevent textarea being shown while dialog is visible.
2018-08-17 18:25:21 +02:00
(win as any).clipboardData.setData("Text", text);
} else if (doc.queryCommandSupported && doc.queryCommandSupported("copy")) {
Dark Theme (#1017) * Stylesheets * Theme Configuration * Options Area * swal2 style * Icon styling * Fix theme not saving * Update English * Update messages.json * dropdown and login logo * btn-link and totp fix * Organisation Styling * Update webauthn-fallback.ts * Fix contrast issues * Add Paypal Container and Loading svg file * Password Generator contrast fix * Dark Mode Fix buttons and foreground * Fix button hover * Fix Styles after rebase * Add hover on nav dropdown-item * Disable Theme Preview * Options Fix for Default Theme Changes * Updated Colour Scheme * Toast fix * Button and Text Styling * Options Update and Messages Fix * Added Search Icon and Fixed Callout styling * Add theme styling to Stripe * Refactor logic for setting color * Reorder logic to avoid race condition * PayPal Loading and Misc Fix * text-state bug fix * Badge Colour Fix * Remove PayPal Tagline The colour cannot be styled so it's not visible on a dark theme * Adding the Styling from #1131 * Update to New Design * Form and Nav restyle * Modal Opacity and Callout * Nav Colours * Missing Borders * Light theme fix * Improved border for listgroup * Change Org Nav Colour * Save theme to localStorage for persistence * Undo change to Wired image * !Important removal and tweaks * Fix regression with navbar * Light theme by default * Refactor to use getEffectiveTheme * Refactor theme constants to use enum * Set theme in index.html before app loads * Use scss selector to set logo image * Export Sass to TS * Update jslib Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2021-09-30 00:06:20 +02:00
const textarea = doc.createElement("textarea");
textarea.textContent = text;
// Prevent scrolling to bottom of page in MS Edge.
textarea.style.position = "fixed";
let copyEl = doc.body;
// For some reason copy command won't work when modal is open if appending to body
if (doc.body.classList.contains("modal-open")) {
copyEl = doc.body.querySelector<HTMLElement>(".modal");
2021-12-17 15:57:11 +01:00
}
Dark Theme (#1017) * Stylesheets * Theme Configuration * Options Area * swal2 style * Icon styling * Fix theme not saving * Update English * Update messages.json * dropdown and login logo * btn-link and totp fix * Organisation Styling * Update webauthn-fallback.ts * Fix contrast issues * Add Paypal Container and Loading svg file * Password Generator contrast fix * Dark Mode Fix buttons and foreground * Fix button hover * Fix Styles after rebase * Add hover on nav dropdown-item * Disable Theme Preview * Options Fix for Default Theme Changes * Updated Colour Scheme * Toast fix * Button and Text Styling * Options Update and Messages Fix * Added Search Icon and Fixed Callout styling * Add theme styling to Stripe * Refactor logic for setting color * Reorder logic to avoid race condition * PayPal Loading and Misc Fix * text-state bug fix * Badge Colour Fix * Remove PayPal Tagline The colour cannot be styled so it's not visible on a dark theme * Adding the Styling from #1131 * Update to New Design * Form and Nav restyle * Modal Opacity and Callout * Nav Colours * Missing Borders * Light theme fix * Improved border for listgroup * Change Org Nav Colour * Save theme to localStorage for persistence * Undo change to Wired image * !Important removal and tweaks * Fix regression with navbar * Light theme by default * Refactor to use getEffectiveTheme * Refactor theme constants to use enum * Set theme in index.html before app loads * Use scss selector to set logo image * Export Sass to TS * Update jslib Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2021-09-30 00:06:20 +02:00
copyEl.appendChild(textarea);
textarea.select();
let success = false;
2021-12-17 15:57:11 +01:00
try {
Dark Theme (#1017) * Stylesheets * Theme Configuration * Options Area * swal2 style * Icon styling * Fix theme not saving * Update English * Update messages.json * dropdown and login logo * btn-link and totp fix * Organisation Styling * Update webauthn-fallback.ts * Fix contrast issues * Add Paypal Container and Loading svg file * Password Generator contrast fix * Dark Mode Fix buttons and foreground * Fix button hover * Fix Styles after rebase * Add hover on nav dropdown-item * Disable Theme Preview * Options Fix for Default Theme Changes * Updated Colour Scheme * Toast fix * Button and Text Styling * Options Update and Messages Fix * Added Search Icon and Fixed Callout styling * Add theme styling to Stripe * Refactor logic for setting color * Reorder logic to avoid race condition * PayPal Loading and Misc Fix * text-state bug fix * Badge Colour Fix * Remove PayPal Tagline The colour cannot be styled so it's not visible on a dark theme * Adding the Styling from #1131 * Update to New Design * Form and Nav restyle * Modal Opacity and Callout * Nav Colours * Missing Borders * Light theme fix * Improved border for listgroup * Change Org Nav Colour * Save theme to localStorage for persistence * Undo change to Wired image * !Important removal and tweaks * Fix regression with navbar * Light theme by default * Refactor to use getEffectiveTheme * Refactor theme constants to use enum * Set theme in index.html before app loads * Use scss selector to set logo image * Export Sass to TS * Update jslib Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2021-09-30 00:06:20 +02:00
// Security exception may be thrown by some browsers.
[Account Switching] [Refactor] Implement new account centric services (#1220) * [chore] updated services.module to use account services * [refactor] sorted services provided by services.module * [chore] removed references to deleted jslib services * [chore] used activeAccount over storageService for account level storage items * [chore] resolved linter warnings * Refactor activeAccountService to stateService * [bug] Remove uneeded calls to state service on logout This was causing console erros on logout. Clearing of data is handled fully in dedicated services, clearing them in state afterwards is essentially a redundant call. * [bug] Add back null locked callback to VaultTimeoutService * Move call to get showUpdateKey * [bug] Ensure HtmlStorageService does not override StateService options and locations * [bug] Adjust theme logic to pull from the new storage locations * [bug] Correct theme not sticking on refresh * [bug] Add enableFullWidth to the account model * [bug] fix theme option empty when light is selected * [bug] init state on application start * [bug] Reinit state when coming back from a lock * [style] Fix lint complaints * [bug] Clean state on logout * [chore] Resolved merge issues * [bug] Correct default for enableGravitars * Bump angular to 12. * Remove angular.json * Bump rxjs * Fix build errors, remove file-loader with asset/resource * Use contenthash * Bump jslib * Bump ngx-toastr * [chore] resolve issues from merge * [chore] resolve issues from merge * [bug] Add missing bracket * Use newer import syntax * [bug] Correct service orge * [style] Fix lint complaints * [chore] update jslib * [review] Address code review * [review] Address code review * [review] Rename providerService to webProviderService Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com> Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-12-14 17:10:26 +01:00
success = doc.execCommand("copy");
if (!success) {
[Account Switching] [Refactor] Implement new account centric services (#1220) * [chore] updated services.module to use account services * [refactor] sorted services provided by services.module * [chore] removed references to deleted jslib services * [chore] used activeAccount over storageService for account level storage items * [chore] resolved linter warnings * Refactor activeAccountService to stateService * [bug] Remove uneeded calls to state service on logout This was causing console erros on logout. Clearing of data is handled fully in dedicated services, clearing them in state afterwards is essentially a redundant call. * [bug] Add back null locked callback to VaultTimeoutService * Move call to get showUpdateKey * [bug] Ensure HtmlStorageService does not override StateService options and locations * [bug] Adjust theme logic to pull from the new storage locations * [bug] Correct theme not sticking on refresh * [bug] Add enableFullWidth to the account model * [bug] fix theme option empty when light is selected * [bug] init state on application start * [bug] Reinit state when coming back from a lock * [style] Fix lint complaints * [bug] Clean state on logout * [chore] Resolved merge issues * [bug] Correct default for enableGravitars * Bump angular to 12. * Remove angular.json * Bump rxjs * Fix build errors, remove file-loader with asset/resource * Use contenthash * Bump jslib * Bump ngx-toastr * [chore] resolve issues from merge * [chore] resolve issues from merge * [bug] Add missing bracket * Use newer import syntax * [bug] Correct service orge * [style] Fix lint complaints * [chore] update jslib * [review] Address code review * [review] Address code review * [review] Rename providerService to webProviderService Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com> Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-12-14 17:10:26 +01:00
this.logService.debug("Copy command unsupported or disabled.");
Dark Theme (#1017) * Stylesheets * Theme Configuration * Options Area * swal2 style * Icon styling * Fix theme not saving * Update English * Update messages.json * dropdown and login logo * btn-link and totp fix * Organisation Styling * Update webauthn-fallback.ts * Fix contrast issues * Add Paypal Container and Loading svg file * Password Generator contrast fix * Dark Mode Fix buttons and foreground * Fix button hover * Fix Styles after rebase * Add hover on nav dropdown-item * Disable Theme Preview * Options Fix for Default Theme Changes * Updated Colour Scheme * Toast fix * Button and Text Styling * Options Update and Messages Fix * Added Search Icon and Fixed Callout styling * Add theme styling to Stripe * Refactor logic for setting color * Reorder logic to avoid race condition * PayPal Loading and Misc Fix * text-state bug fix * Badge Colour Fix * Remove PayPal Tagline The colour cannot be styled so it's not visible on a dark theme * Adding the Styling from #1131 * Update to New Design * Form and Nav restyle * Modal Opacity and Callout * Nav Colours * Missing Borders * Light theme fix * Improved border for listgroup * Change Org Nav Colour * Save theme to localStorage for persistence * Undo change to Wired image * !Important removal and tweaks * Fix regression with navbar * Light theme by default * Refactor to use getEffectiveTheme * Refactor theme constants to use enum * Set theme in index.html before app loads * Use scss selector to set logo image * Export Sass to TS * Update jslib Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2021-09-30 00:06:20 +02:00
}
2018-06-05 21:02:53 +02:00
} catch (e) {
2022-02-24 12:10:07 +01:00
// eslint-disable-next-line
2018-06-05 21:02:53 +02:00
console.warn("Copy to clipboard failed.", e);
} finally {
2018-07-26 04:01:26 +02:00
copyEl.removeChild(textarea);
2021-12-17 15:57:11 +01:00
}
return success;
}
2021-12-17 15:57:11 +01:00
}
2019-02-27 04:42:30 +01:00
readFromClipboard(options?: any): Promise<string> {
throw new Error("Cannot read from clipboard on web.");
2021-12-17 15:57:11 +01:00
}
supportsBiometric() {
2021-04-07 20:42:57 +02:00
return Promise.resolve(false);
2021-12-17 15:57:11 +01:00
}
authenticateBiometric() {
2021-04-07 20:42:57 +02:00
return Promise.resolve(false);
2021-12-17 15:57:11 +01:00
}
supportsSecureStorage() {
return false;
2021-12-17 15:57:11 +01:00
}
2018-06-05 21:02:53 +02:00
}