mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 20:24:01 +00:00
PM-20532 - WIP on send token stuff
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { SendHashedPassword } from "../../../key-management/sends/send-password.service";
|
||||
import { SendAccessToken } from "../models/send-access-token";
|
||||
import { SendTokenRetrievalError } from "../services/send-token.service";
|
||||
import { TryGetSendAccessTokenError } from "../services/send-token.service";
|
||||
|
||||
export type SendAccessCredentialsType = "password" | "email-otp";
|
||||
|
||||
@@ -31,9 +31,20 @@ export abstract class SendTokenService {
|
||||
|
||||
// TODO: define return types.
|
||||
// TODO: consider converting to observable.
|
||||
/**
|
||||
* Attempts to retrieve a SendAccessToken for the given sendId.
|
||||
* If the access token is found in session storage and is not expired, then it returns the token.
|
||||
* If the access token is expired, then it returns a SendTokenRetrievalError expired error.
|
||||
* If an access token is not found in storage, then it attempts to retrieve it from the server (will succeed for sends that don't require any credentials to view).
|
||||
* If the access token is successfully retrieved from the server, then it stores the token in session storage and returns it.
|
||||
* If an access token cannot be granted b/c the send requires credentials, then it returns a SendTokenRetrievalError indicating which credentials are required.
|
||||
* Any submissions of credentials will be handled by the getSendAccessTokenWithCredentials method.
|
||||
* @param sendId The ID of the send to retrieve the access token for.
|
||||
* @returns A promise that resolves to a SendAccessToken if found and valid, or a SendTokenRetrievalError if not.
|
||||
*/
|
||||
abstract tryGetSendAccessToken: (
|
||||
sendId: string,
|
||||
) => Promise<SendAccessToken | SendTokenRetrievalError>;
|
||||
) => Promise<SendAccessToken | TryGetSendAccessTokenError>;
|
||||
|
||||
abstract getSendAccessTokenWithCredentials: (
|
||||
sendId: string,
|
||||
|
||||
@@ -8,6 +8,9 @@ import { SendAccessToken } from "../models/send-access-token";
|
||||
|
||||
export type SendTokenApiRetrievalError = "password-required" | "otp-required" | "unknown-error";
|
||||
|
||||
// Consider adding types for submission with credentials:
|
||||
// | "invalid-password"
|
||||
|
||||
export class SendTokenApiService implements SendTokenApiServiceAbstraction {
|
||||
constructor(
|
||||
private environmentService: EnvironmentService,
|
||||
|
||||
@@ -33,7 +33,9 @@ export const SEND_ACCESS_TOKEN_DICT = KeyDefinition.record<SendAccessToken, stri
|
||||
},
|
||||
);
|
||||
|
||||
export type SendTokenRetrievalError = "expired" | SendTokenApiRetrievalError;
|
||||
// TODO: add different error types for each method.
|
||||
export type TryGetSendAccessTokenError = "expired" | SendTokenApiRetrievalError;
|
||||
// export type GetSendAccessTokenWithCredsError = <subset of SendTokenApiRetrievalError>;
|
||||
|
||||
export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
private sendAccessTokenDictGlobalState: GlobalState<Record<string, SendAccessToken>> | undefined;
|
||||
@@ -50,9 +52,13 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
this.sendAccessTokenDictGlobalState = this.globalStateProvider.get(SEND_ACCESS_TOKEN_DICT);
|
||||
}
|
||||
|
||||
async tryGetSendAccessToken(sendId: string): Promise<SendAccessToken | SendTokenRetrievalError> {
|
||||
// TODO: check in storage for the access token and if it is expired.
|
||||
async tryGetSendAccessToken(
|
||||
sendId: string,
|
||||
): Promise<SendAccessToken | TryGetSendAccessTokenError> {
|
||||
// Validate the sendId is a non-empty string.
|
||||
this.validateSendId(sendId);
|
||||
|
||||
// Check in storage for the access token for the given sendId.
|
||||
const sendAccessTokenFromStorage = await this.getSendAccessTokenFromStorage(sendId);
|
||||
|
||||
if (sendAccessTokenFromStorage != null) {
|
||||
@@ -60,7 +66,7 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
if (sendAccessTokenFromStorage.isExpired()) {
|
||||
return "expired";
|
||||
} else {
|
||||
// If it is not expired, we return
|
||||
// If it is not expired, we return it
|
||||
return sendAccessTokenFromStorage;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +74,6 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
// If we don't have a token in storage, we can try to request a new token from the server.
|
||||
const request = new SendAccessTokenRequest(sendId);
|
||||
|
||||
// try {
|
||||
const result = await this.sendTokenApiService.requestSendAccessToken(request);
|
||||
|
||||
if (result instanceof SendAccessToken) {
|
||||
@@ -82,13 +87,28 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
|
||||
async getSendAccessTokenWithCredentials(
|
||||
sendId: string,
|
||||
sendCredentials: SendAccessCredentials | undefined,
|
||||
sendCredentials: SendAccessCredentials,
|
||||
): Promise<void> {
|
||||
// TODO: check in storage for the access token and if it is expired.
|
||||
// If it is expired, we will need to request a new token from the server.
|
||||
// If it is not expired, we will return the token from storage.
|
||||
// const request = new SendAccessTokenRequest(sendId, sendCredentials);
|
||||
// const result = await this.sendTokenApiService.requestSendAccessToken(request);
|
||||
// Validate the sendId
|
||||
this.validateSendId(sendId);
|
||||
|
||||
// Validate the credentials
|
||||
if (sendCredentials == null) {
|
||||
throw new Error("sendCredentials must be provided.");
|
||||
}
|
||||
|
||||
// Request the access token from the server using the provided credentials.
|
||||
const request = new SendAccessTokenRequest(sendId, sendCredentials);
|
||||
const result = await this.sendTokenApiService.requestSendAccessToken(request);
|
||||
|
||||
if (result instanceof SendAccessToken) {
|
||||
// If we get a token back, we need to store it in the global state.
|
||||
await this.setSendAccessTokenInStorage(sendId, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle errors from the API service.
|
||||
// return result;
|
||||
}
|
||||
|
||||
async hashPassword(password: string, keyMaterialUrlB64: string): Promise<SendHashedPassword> {
|
||||
@@ -118,4 +138,10 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private validateSendId(sendId: string): void {
|
||||
if (sendId == null || sendId.trim() === "") {
|
||||
throw new Error("sendId must be provided.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user