1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 00:33:44 +00:00

feat(tokens): Allow Inactive user authenticated API calls

This commit is contained in:
Justin Baur
2025-09-03 10:09:02 -04:00
committed by GitHub
parent bcd7eb746a
commit 73e8532ecc
15 changed files with 406 additions and 362 deletions

View File

@@ -78,7 +78,7 @@ export class SignalRConnectionService {
return new Observable<SignalRNotification>((subsciber) => {
const connection = this.hubConnectionBuilderFactory()
.withUrl(notificationsUrl + "/hub", {
accessTokenFactory: () => this.apiService.getActiveBearerToken(),
accessTokenFactory: () => this.apiService.getActiveBearerToken(userId),
skipNegotiation: true,
transport: HttpTransportType.WebSockets,
})

View File

@@ -1,3 +1,5 @@
import { UserId } from "@bitwarden/user-core";
import { ApiService } from "../../../abstractions/api.service";
import { AppIdService } from "../../abstractions/app-id.service";
@@ -12,13 +14,13 @@ export class WebPushNotificationsApiService {
/**
* Posts a device-user association to the server and ensures it's installed for push server notifications
*/
async putSubscription(pushSubscription: PushSubscriptionJSON): Promise<void> {
async putSubscription(pushSubscription: PushSubscriptionJSON, userId: UserId): Promise<void> {
const request = WebPushRequest.from(pushSubscription);
await this.apiService.send(
"POST",
`/devices/identifier/${await this.appIdService.getAppId()}/web-push-auth`,
request,
true,
userId,
false,
);
}

View File

@@ -143,7 +143,7 @@ class MyWebPushConnector implements WebPushConnector {
await subscriptionUsersState.update(() => subscriptionUsers);
// Inform the server about the new subscription-user association
await this.webPushApiService.putSubscription(subscription.toJSON());
await this.webPushApiService.putSubscription(subscription.toJSON(), this.userId);
}),
switchMap(() => this.pushEvent$),
map((e) => {

View File

@@ -1,22 +1,21 @@
import { ApiService } from "../../../abstractions/api.service";
import { TokenService } from "../../../auth/abstractions/token.service";
import { UserId } from "../../../types/guid";
import { ConfigApiServiceAbstraction } from "../../abstractions/config/config-api.service.abstraction";
import { ServerConfigResponse } from "../../models/response/server-config.response";
export class ConfigApiService implements ConfigApiServiceAbstraction {
constructor(
private apiService: ApiService,
private tokenService: TokenService,
) {}
constructor(private apiService: ApiService) {}
async get(userId: UserId | null): Promise<ServerConfigResponse> {
// Authentication adds extra context to config responses, if the user has an access token, we want to use it
// We don't particularly care about ensuring the token is valid and not expired, just that it exists
const authed: boolean =
userId == null ? false : (await this.tokenService.getAccessToken(userId)) != null;
let r: any;
if (userId == null) {
r = await this.apiService.send("GET", "/config", null, false, true);
} else {
r = await this.apiService.send("GET", "/config", null, userId, true);
}
const r = await this.apiService.send("GET", "/config", null, authed, true);
return new ServerConfigResponse(r);
}
}