mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 04:03:29 +00:00
PM-20532 - More service layer refactors and wiring up error handling.
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
import { Jsonify } from "type-fest";
|
||||
|
||||
export interface SendAccessTokenJson {
|
||||
access_token: string;
|
||||
expires_in: number; // in seconds
|
||||
scope: string;
|
||||
token_type: string;
|
||||
}
|
||||
|
||||
export class SendAccessToken {
|
||||
constructor(
|
||||
/**
|
||||
@@ -14,12 +21,11 @@ export class SendAccessToken {
|
||||
|
||||
/**
|
||||
* Builds an instance from our Identity token response data
|
||||
* @param accessToken The `access_token` string
|
||||
* @param expiresInSeconds The `expires_in` value (in seconds)
|
||||
* @param sendAccessTokenJson The JSON data from the Identity token response
|
||||
*/
|
||||
static fromResponseData(accessToken: string, expiresInSeconds: number): SendAccessToken {
|
||||
const expiresAtTimeStamp = Date.now() + expiresInSeconds * 1000;
|
||||
return new SendAccessToken(accessToken, expiresAtTimeStamp);
|
||||
static fromResponseData(sendAccessTokenJson: SendAccessTokenJson): SendAccessToken {
|
||||
const expiresAtTimeStamp = Date.now() + sendAccessTokenJson.expires_in * 1000;
|
||||
return new SendAccessToken(sendAccessTokenJson.access_token, expiresAtTimeStamp);
|
||||
}
|
||||
|
||||
/** Returns whether the send access token is expired or not */
|
||||
|
||||
@@ -8,7 +8,7 @@ import { SendAccessToken } from "../models/send-access-token";
|
||||
|
||||
export type SendTokenApiRetrievalError =
|
||||
| "password-required"
|
||||
| "otp-required"
|
||||
| "email-and-otp-required"
|
||||
| "invalid-password"
|
||||
| "invalid-otp"
|
||||
| "unknown-error";
|
||||
@@ -45,11 +45,16 @@ export class SendTokenApiService implements SendTokenApiServiceAbstraction {
|
||||
const responseJson = await response.json();
|
||||
|
||||
if (response.status === 200) {
|
||||
const sendAccessToken = SendAccessToken.fromJson(responseJson);
|
||||
const sendAccessToken = SendAccessToken.fromResponseData(responseJson);
|
||||
return sendAccessToken;
|
||||
} else if (response.status === 400) {
|
||||
// TODO: add correct error handling for 400
|
||||
return "password-required";
|
||||
if (responseJson?.error === "invalid_request") {
|
||||
if (responseJson?.error_description === "Password is required.") {
|
||||
return "password-required";
|
||||
} else if (responseJson?.error_description === "Email and OTP are required.") {
|
||||
return "email-and-otp-required";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "unknown-error";
|
||||
|
||||
@@ -35,13 +35,15 @@ export const SEND_ACCESS_TOKEN_DICT = KeyDefinition.record<SendAccessToken, stri
|
||||
|
||||
type CredentialsRequiredApiError = Extract<
|
||||
SendTokenApiRetrievalError,
|
||||
"password-required" | "otp-required" | "unknown-error"
|
||||
"password-required" | "email-and-otp-required" | "unknown-error"
|
||||
>;
|
||||
|
||||
function isCredentialsRequiredApiError(
|
||||
error: SendTokenApiRetrievalError,
|
||||
): error is CredentialsRequiredApiError {
|
||||
return error === "password-required" || error === "otp-required" || error === "unknown-error";
|
||||
return (
|
||||
error === "password-required" || error === "email-and-otp-required" || error === "unknown-error"
|
||||
);
|
||||
}
|
||||
|
||||
export type TryGetSendAccessTokenError = "expired" | CredentialsRequiredApiError;
|
||||
@@ -104,7 +106,7 @@ export class SendTokenService implements SendTokenServiceAbstraction {
|
||||
|
||||
if (isCredentialsRequiredApiError(result)) {
|
||||
// If we get an expected API error, we return it.
|
||||
// Typically, this will be a "password-required" or "otp-required" error to communicate that the send requires credentials to access.
|
||||
// Typically, this will be a "password-required" or "email-and-otp-required" error to communicate that the send requires credentials to access.
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user