1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-11 14:04:03 +00:00

Passkey stuff

Co-authored-by: Anders Åberg <github@andersaberg.com>
This commit is contained in:
Justin Baur
2024-09-06 09:27:55 -04:00
committed by Anders Åberg
parent 2a956744bd
commit 54cc54272e
5 changed files with 165 additions and 44 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -52,6 +52,7 @@ import { TwoFactorComponent } from "../auth/two-factor.component";
import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component";
import { VaultComponent } from "../vault/app/vault/vault.component";
import { PasskeysComponent } from "./components/passkeys.component";
import { SendComponent } from "./tools/send/send.component";
/**
@@ -200,6 +201,10 @@ const routes: Routes = [
],
},
),
{
path: "passkeys",
component: PasskeysComponent,
},
{
path: "",
component: AnonLayoutWrapperComponent,

View File

@@ -0,0 +1,22 @@
import { Component } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
export type BrowserSyncVerificationDialogParams = {
fingerprint: string[];
};
@Component({
standalone: true,
template: `
<img
src="../resources/passkeys.png"
class="mb-4 logo"
alt="Bitwarden"
width="660"
height="580"
/>
`,
imports: [JslibModule],
})
export class PasskeysComponent {}

View File

@@ -1,4 +1,5 @@
import * as path from "path";
import * as url from "url";
import { app, BrowserWindow, Menu, MenuItemConstructorOptions, nativeImage, Tray } from "electron";
import { firstValueFrom } from "rxjs";
@@ -6,6 +7,7 @@ import { firstValueFrom } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { DesktopSettingsService } from "../platform/services/desktop-settings.service";
import { cleanUserAgent } from "../utils";
import { WindowMain } from "./window.main";
@@ -44,6 +46,10 @@ export class TrayMain {
label: this.i18nService.t("showHide"),
click: () => this.toggleWindow(),
},
{
label: "Fake Popup",
click: () => this.fakePopup(),
},
{ type: "separator" },
{
label: this.i18nService.t("exit"),
@@ -195,4 +201,47 @@ export class TrayMain {
this.windowMain.win.close();
}
}
private async fakePopup() {
if (this.windowMain.win == null || this.windowMain.win.isDestroyed()) {
await this.windowMain.createWindow("minimal-app");
return;
}
// Restyle existing
const existingWin = this.windowMain.win;
existingWin.setBounds({
width: 400,
height: 600,
});
existingWin.setSize(400, 600, true);
existingWin.setWindowButtonVisibility(false);
existingWin.resizable = false;
await existingWin.loadURL(
url.format({
protocol: "file:",
//pathname: `${__dirname}/index.html`,
pathname: path.join(__dirname, "/index.html"),
slashes: true,
hash: "/passkeys",
query: {
redirectUrl: "/passkeys",
},
}),
{
userAgent: cleanUserAgent(existingWin.webContents.userAgent),
},
);
existingWin.center();
existingWin.setAlwaysOnTop(true);
existingWin.show();
// TODO: Do things
// ?? Enqueue the browser location
// Change browser location and styling to minimal
// Show popup
// Change styling back to full
// ?? Dequeue browser location
}
}

View File

@@ -168,39 +168,66 @@ export class WindowMain {
});
}
async createWindow(): Promise<void> {
this.windowStates[mainWindowSizeKey] = await this.getWindowState(
this.defaultWidth,
this.defaultHeight,
);
this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$);
async createWindow(template: "full-app" | "minimal-app" = "full-app"): Promise<void> {
if (template === "full-app") {
this.windowStates[mainWindowSizeKey] = await this.getWindowState(
this.defaultWidth,
this.defaultHeight,
);
this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$);
this.session = session.fromPartition("persist:bitwarden", { cache: false });
this.session = session.fromPartition("persist:bitwarden", { cache: false });
// Create the browser window.
this.win = new BrowserWindow({
width: this.windowStates[mainWindowSizeKey].width,
height: this.windowStates[mainWindowSizeKey].height,
minWidth: 680,
minHeight: 500,
x: this.windowStates[mainWindowSizeKey].x,
y: this.windowStates[mainWindowSizeKey].y,
title: app.name,
icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined,
titleBarStyle: isMac() ? "hiddenInset" : undefined,
show: false,
backgroundColor: await this.getBackgroundColor(),
alwaysOnTop: this.enableAlwaysOnTop,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
spellcheck: false,
nodeIntegration: false,
backgroundThrottling: false,
contextIsolation: true,
session: this.session,
devTools: isDev(),
},
});
// Create the browser window.
this.win = new BrowserWindow({
width: this.windowStates[mainWindowSizeKey].width,
height: this.windowStates[mainWindowSizeKey].height,
minWidth: 680,
minHeight: 500,
x: this.windowStates[mainWindowSizeKey].x,
y: this.windowStates[mainWindowSizeKey].y,
title: app.name,
icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined,
titleBarStyle: isMac() ? "hiddenInset" : undefined,
show: false,
backgroundColor: await this.getBackgroundColor(),
alwaysOnTop: this.enableAlwaysOnTop,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
spellcheck: false,
nodeIntegration: false,
backgroundThrottling: false,
contextIsolation: true,
session: this.session,
devTools: isDev(),
},
});
} else {
//
this.win = new BrowserWindow({
width: 400,
height: 600,
resizable: false,
icon: null,
center: true,
titleBarStyle: "hiddenInset",
frame: false,
alwaysOnTop: true,
backgroundColor: await this.getBackgroundColor(),
show: true,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
spellcheck: false,
nodeIntegration: false,
backgroundThrottling: false,
contextIsolation: true,
session: this.session,
devTools: isDev(),
},
});
this.win.setWindowButtonVisibility(false);
}
this.win.webContents.on("dom-ready", () => {
this.win.webContents.zoomFactor = this.windowStates[mainWindowSizeKey].zoomFactor ?? 1.0;
@@ -213,19 +240,37 @@ export class WindowMain {
// Show it later since it might need to be maximized.
this.win.show();
// and load the index.html of the app.
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.win.loadURL(
url.format({
protocol: "file:",
pathname: path.join(__dirname, "/index.html"),
slashes: true,
}),
{
userAgent: cleanUserAgent(this.win.webContents.userAgent),
},
);
if (template === "full-app") {
// and load the index.html of the app.
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.win.loadURL(
url.format({
protocol: "file:",
pathname: path.join(__dirname, "/index.html"),
slashes: true,
}),
{
userAgent: cleanUserAgent(this.win.webContents.userAgent),
},
);
} else {
await this.win.loadURL(
url.format({
protocol: "file:",
//pathname: `${__dirname}/index.html`,
pathname: path.join(__dirname, "/index.html"),
slashes: true,
hash: "/passkeys",
query: {
redirectUrl: "/passkeys",
},
}),
{
userAgent: cleanUserAgent(this.win.webContents.userAgent),
},
);
}
// Open the DevTools.
if (isDev()) {