diff --git a/Dockerfile b/Dockerfile
index a73d32e..b3623a5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,7 +17,7 @@
# docker cp $image_id:/bw_web_vault.tar.gz .
# docker rm $image_id
-FROM node:16-bullseye as build
+FROM node:16-bookworm as build
RUN node --version && npm --version
# Prepare the folder to enable non-root, otherwise npm will refuse to run the postinstall
@@ -28,8 +28,8 @@ USER node
# Can be a tag, release, but prefer a commit hash because it's not changeable
# https://github.com/bitwarden/clients/commit/${VAULT_VERSION}
#
-# Using https://github.com/bitwarden/clients/releases/tag/web-v2023.7.1
-ARG VAULT_VERSION=42cbdbd25284460c2d9f02e3bdd8df962080b4d2
+# Using https://github.com/bitwarden/clients/releases/tag/web-v2023.8.2
+ARG VAULT_VERSION=b403f2bcc79426abb9d8f02c391b7c8158876960
WORKDIR /vault
RUN git init
diff --git a/patches/v2023.8.2.patch b/patches/v2023.8.2.patch
new file mode 100644
index 0000000..47d310c
--- /dev/null
+++ b/patches/v2023.8.2.patch
@@ -0,0 +1,515 @@
+diff --git a/apps/web/src/app/admin-console/organizations/create/organization-information.component.html b/apps/web/src/app/admin-console/organizations/create/organization-information.component.html
+index 6029cfd833..04324b7d19 100644
+--- a/apps/web/src/app/admin-console/organizations/create/organization-information.component.html
++++ b/apps/web/src/app/admin-console/organizations/create/organization-information.component.html
+@@ -12,7 +12,7 @@
+
+
+
+- {{ "billingEmail" | i18n }}
++ {{ "email" | i18n }}
+
+
+
+diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.html b/apps/web/src/app/admin-console/organizations/settings/account.component.html
+index c7ac9910ac..e03c8fedcb 100644
+--- a/apps/web/src/app/admin-console/organizations/settings/account.component.html
++++ b/apps/web/src/app/admin-console/organizations/settings/account.component.html
+@@ -15,7 +15,7 @@
+
+
+
+- {{ "billingEmail" | i18n }}
++ {{ "email" | i18n }}
+
+
+
+diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts
+index cfac9d0693..fab4dc991a 100644
+--- a/apps/web/src/app/app.component.ts
++++ b/apps/web/src/app/app.component.ts
+@@ -184,6 +184,10 @@ export class AppComponent implements OnDestroy, OnInit {
+ break;
+ }
+ case "showToast":
++ if (typeof message.text === "string" && typeof crypto.subtle === "undefined") {
++ message.title = "This browser requires HTTPS to use the web vault";
++ message.text = "Check the Vaultwarden wiki for details on how to enable it";
++ }
+ this.showToast(message);
+ break;
+ case "setFullWidth":
+diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts
+index 29cc6df156..3dbbfbd858 100644
+--- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts
++++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts
+@@ -109,11 +109,11 @@ export class TwoFactorAuthenticatorComponent
+ new window.QRious({
+ element: document.getElementById("qr"),
+ value:
+- "otpauth://totp/Bitwarden:" +
++ "otpauth://totp/Vaultwarden:" +
+ Utils.encodeRFC3986URIComponent(email) +
+ "?secret=" +
+ encodeURIComponent(this.key) +
+- "&issuer=Bitwarden",
++ "&issuer=Vaultwarden",
+ size: 160,
+ });
+ }, 100);
+diff --git a/apps/web/src/app/billing/organizations/organization-billing-history-view.component.ts b/apps/web/src/app/billing/organizations/organization-billing-history-view.component.ts
+index 22cea10acb..747f534bcc 100644
+--- a/apps/web/src/app/billing/organizations/organization-billing-history-view.component.ts
++++ b/apps/web/src/app/billing/organizations/organization-billing-history-view.component.ts
+@@ -45,7 +45,7 @@ export class OrgBillingHistoryViewComponent implements OnInit, OnDestroy {
+ return;
+ }
+ this.loading = true;
+- this.billing = await this.organizationApiService.getBilling(this.organizationId);
++ this.billing = null;
+ this.loading = false;
+ }
+ }
+diff --git a/apps/web/src/app/components/environment-selector/environment-selector.component.ts b/apps/web/src/app/components/environment-selector/environment-selector.component.ts
+index 9f736a72e4..ee48329588 100644
+--- a/apps/web/src/app/components/environment-selector/environment-selector.component.ts
++++ b/apps/web/src/app/components/environment-selector/environment-selector.component.ts
+@@ -30,7 +30,7 @@ export class EnvironmentSelectorComponent implements OnInit {
+ this.isEuServer = domain.includes(RegionDomain.EU);
+ this.isUsServer = domain.includes(RegionDomain.US) || domain.includes(RegionDomain.USQA);
+ this.selectedRegionImageName = this.getRegionImage();
+- this.showRegionSelector = !this.platformUtilsService.isSelfHost();
++ this.showRegionSelector = false;
+ }
+
+ getRegionImage(): string {
+diff --git a/apps/web/src/app/core/init.service.ts b/apps/web/src/app/core/init.service.ts
+index 3437c4f3e9..7337f2dcdc 100644
+--- a/apps/web/src/app/core/init.service.ts
++++ b/apps/web/src/app/core/init.service.ts
+@@ -7,10 +7,7 @@ import { NotificationsService as NotificationsServiceAbstraction } from "@bitwar
+ import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
+ import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
+ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
+-import {
+- EnvironmentService as EnvironmentServiceAbstraction,
+- Urls,
+-} from "@bitwarden/common/platform/abstractions/environment.service";
++import { EnvironmentService as EnvironmentServiceAbstraction } from "@bitwarden/common/platform/abstractions/environment.service";
+ import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
+ import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
+ import { ContainerService } from "@bitwarden/common/platform/services/container.service";
+@@ -36,11 +33,23 @@ export class InitService {
+ ) {}
+
+ init() {
++ function getBaseUrl() {
++ // If the base URL is `https://vaultwarden.example.com/base/path/`,
++ // `window.location.href` should have one of the following forms:
++ //
++ // - `https://vaultwarden.example.com/base/path/`
++ // - `https://vaultwarden.example.com/base/path/#/some/route[?queryParam=...]`
++ //
++ // We want to get to just `https://vaultwarden.example.com/base/path`.
++ let baseUrl = window.location.href;
++ baseUrl = baseUrl.replace(/#.*/, ""); // Strip off `#` and everything after.
++ baseUrl = baseUrl.replace(/\/+$/, ""); // Trim any trailing `/` chars.
++ return baseUrl;
++ }
+ return async () => {
+ await this.stateService.init();
+
+- const urls = process.env.URLS as Urls;
+- urls.base ??= this.win.location.origin;
++ const urls = { base: getBaseUrl() };
+ await this.environmentService.setUrls(urls);
+ // Workaround to ignore stateService.activeAccount until process.env.URLS are set
+ // TODO: Remove this when implementing ticket PM-2637
+diff --git a/apps/web/src/app/core/router.service.ts b/apps/web/src/app/core/router.service.ts
+index 82399d4e49..56e72cdcdb 100644
+--- a/apps/web/src/app/core/router.service.ts
++++ b/apps/web/src/app/core/router.service.ts
+@@ -23,7 +23,7 @@ export class RouterService {
+ .subscribe((event: NavigationEnd) => {
+ this.currentUrl = event.url;
+
+- let title = i18nService.t("bitWebVault");
++ let title = "Vaultwarden Web";
+
+ if (this.currentUrl.includes("/sm/")) {
+ title = i18nService.t("bitSecretsManager");
+diff --git a/apps/web/src/app/core/web-platform-utils.service.ts b/apps/web/src/app/core/web-platform-utils.service.ts
+index ec829d71fb..f3a362d0e7 100644
+--- a/apps/web/src/app/core/web-platform-utils.service.ts
++++ b/apps/web/src/app/core/web-platform-utils.service.ts
+@@ -133,15 +133,15 @@ export class WebPlatformUtilsService implements PlatformUtilsService {
+ }
+
+ isDev(): boolean {
+- return process.env.NODE_ENV === "development";
++ return false;
+ }
+
+ isSelfHost(): boolean {
+- return WebPlatformUtilsService.isSelfHost();
++ return false;
+ }
+
+ static isSelfHost(): boolean {
+- return process.env.ENV.toString() === "selfhosted";
++ return false;
+ }
+
+ copyToClipboard(text: string, options?: any): void | boolean {
+diff --git a/apps/web/src/app/layouts/footer.component.html b/apps/web/src/app/layouts/footer.component.html
+index 8cacb4ceba..0504559697 100644
+--- a/apps/web/src/app/layouts/footer.component.html
++++ b/apps/web/src/app/layouts/footer.component.html
+@@ -1,7 +1,9 @@
+