Skip to content

Commit

Permalink
Proof of concept for brave/brave-browser#33031
Browse files Browse the repository at this point in the history
Needs more work (UI mock ups, tests, etc)
  • Loading branch information
bsclifton committed Oct 17, 2024
1 parent d67b8d0 commit 6d954aa
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 19 deletions.
38 changes: 21 additions & 17 deletions components/brave_vpn/browser/brave_vpn_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ void BraveVpnService::UpdatePurchasedStateForSessionExpired(
return;
}

SetPurchasedState(env, PurchasedState::SESSION_EXPIRED);
SetPurchasedState(env, out_of_credentials ? PurchasedState::OUT_OF_CREDENTIALS
: PurchasedState::SESSION_EXPIRED);
}

bool BraveVpnService::IsCurrentRegionSelectedAutomatically(
Expand Down Expand Up @@ -572,6 +573,8 @@ void BraveVpnService::OnCredentialSummary(const std::string& domain,
std::string summary_string_trimmed;
base::TrimWhitespaceASCII(summary->message, base::TrimPositions::TRIM_ALL,
&summary_string_trimmed);
//SetPurchasedState(env, PurchasedState::OUT_OF_CREDENTIALS);
//return;
if (summary_string_trimmed.length() == 0) {
// no credential found; person needs to login
VLOG(1) << __func__ << " : No credential found; user needs to login!";
Expand Down Expand Up @@ -678,6 +681,7 @@ void BraveVpnService::OnPrepareCredentialsPresentation(
return;
}

out_of_credentials = false;
SetSkusCredential(local_prefs_, credential, time);

if (GetCurrentEnvironment() != env) {
Expand Down Expand Up @@ -716,28 +720,28 @@ void BraveVpnService::OnGetSubscriberCredentialV12(
return;
}

// If we get here, we've already tried two credentials (the retry failed).
// We can set the state as FAILED and do not attempt to get another
// credential. The cached credential will eventually expire and user will
// fetch a new one.
//
// There could be two reasons for this.

// 1. We've already tried two credentials (the retry failed).
if (token_no_longer_valid && IsRetriedSkusCredential(local_prefs_)) {
VLOG(2) << __func__
<< " : Got TokenNoLongerValid again with retried skus credential";
out_of_credentials = true;
SetPurchasedState(
GetCurrentEnvironment(), PurchasedState::FAILED,
l10n_util::GetStringUTF8(IDS_BRAVE_VPN_PURCHASE_TOKEN_NOT_VALID));
return;
}

// When this path is reached:
// - The cached credential is considered good but vendor side has an error.
// That could be a network outage or a server side error on vendor side.
// OR
// - The cached credential is consumed and we've now tried two different
// credentials.
//
// We set the state as FAILED and do not attempt to get another credential.
// Cached credential will eventually expire and user will fetch a new one.
//
// This logic can be updated if we issue more than two credentials per day.
auto message_id = token_no_longer_valid
? IDS_BRAVE_VPN_PURCHASE_TOKEN_NOT_VALID
: IDS_BRAVE_VPN_PURCHASE_CREDENTIALS_FETCH_FAILED;
// 2. The cached credential is considered good but vendor side has an error.
// That could be a network outage or a server side error on vendor side.
SetPurchasedState(GetCurrentEnvironment(), PurchasedState::FAILED,
l10n_util::GetStringUTF8(message_id));
l10n_util::GetStringUTF8(
IDS_BRAVE_VPN_PURCHASE_CREDENTIALS_FETCH_FAILED));
#endif
return;
}
Expand Down
1 change: 1 addition & 0 deletions components/brave_vpn/browser/brave_vpn_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ class BraveVpnService :
std::unique_ptr<BraveVPNServiceDelegate> delegate_;
base::RepeatingTimer p3a_timer_;
base::OneShotTimer subs_cred_refresh_timer_;
bool out_of_credentials = false;
base::WeakPtrFactory<BraveVpnService> weak_ptr_factory_{this};
};

Expand Down
1 change: 1 addition & 0 deletions components/brave_vpn/common/mojom/brave_vpn.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ enum PurchasedState {
LOADING,
SESSION_EXPIRED,
FAILED,
OUT_OF_CREDENTIALS,
};

struct PurchasedInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ function MainPanel() {
const isSelectingRegion = useSelector((state) => state.isSelectingRegion)
const connectionStatus = useSelector((state) => state.connectionStatus)
const expired = useSelector((state) => state.expired)
const outOfCredentials = useSelector((state) => state.outOfCredentials)
const regions = useSelector((state) => state.regions)

const onSelectRegionButtonClick = () => {
Expand Down Expand Up @@ -184,6 +185,15 @@ function MainPanel() {
<SessionExpiredContent />
</S.StyledAlert>
)}
{outOfCredentials && (
<S.StyledAlert
type='warning'
mode='full'
hideIcon
>
<div slot='title'>OUT OF CREDENTIALS</div>
</S.StyledAlert>
)}
<S.RegionSelectorButton
type='button'
onClick={onSelectRegionButtonClick}
Expand Down
2 changes: 2 additions & 0 deletions components/brave_vpn/resources/panel/state/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type showMainViewPayload = {
regions: Region[]
connectionStatus: ConnectionState
expired: boolean
outOfCredentials: boolean
}

export type initializedPayload = {
Expand All @@ -45,6 +46,7 @@ export const connectionFailed = createAction('connectionFailed')
export const initialize = createAction('initialize')
export const purchaseConfirmed = createAction('purchaseConfirmed')
export const purchaseExpired = createAction('purchaseExpired')
export const outOfCredentials = createAction('outOfCredentials')
export const showSellView = createAction('showSellView')
export const showLoadingView = createAction('showLoadingView')
export const resetConnectionState = createAction('resetConnectionState')
Expand Down
23 changes: 21 additions & 2 deletions components/brave_vpn/resources/panel/state/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ handler.on(Actions.purchaseConfirmed.getType(), async (store) => {
state === ConnectionState.CONNECT_FAILED
? ConnectionState.DISCONNECTED
: state /* Treat connection failure on startup as disconnected */,
expired: false
expired: false,
outOfCredentials: false
})
)
})
Expand All @@ -86,7 +87,25 @@ handler.on(Actions.purchaseExpired.getType(), async (store) => {
currentRegion,
regions,
connectionStatus: ConnectionState.DISCONNECTED,
expired: true
expired: true,
outOfCredentials: false
})
)
})

handler.on(Actions.outOfCredentials.getType(), async (store) => {
const [{ currentRegion }, { regions }] = await Promise.all([
getPanelBrowserAPI().serviceHandler.getSelectedRegion(),
getPanelBrowserAPI().serviceHandler.getAllRegions()
])

store.dispatch(
Actions.showMainView({
currentRegion,
regions,
connectionStatus: ConnectionState.DISCONNECTED,
expired: false,
outOfCredentials: true
})
)
})
Expand Down
3 changes: 3 additions & 0 deletions components/brave_vpn/resources/panel/state/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type RootState = {
hasError: boolean
isSelectingRegion: boolean
expired: boolean
outOfCredentials: boolean
connectionStatus: ConnectionState
regions: Region[]
currentRegion: Region
Expand All @@ -25,6 +26,7 @@ const defaultState: RootState = {
hasError: false,
isSelectingRegion: false,
expired: false,
outOfCredentials: false,
connectionStatus: ConnectionState.DISCONNECTED,
regions: [],
currentRegion: new Region(),
Expand Down Expand Up @@ -148,6 +150,7 @@ reducer.on(Actions.showMainView, (state, payload): RootState => {
return {
...state,
expired: payload.expired,
outOfCredentials: payload.outOfCredentials,
currentRegion: payload.currentRegion,
regions: payload.regions,
connectionStatus: payload.connectionStatus,
Expand Down
3 changes: 3 additions & 0 deletions components/brave_vpn/resources/panel/state/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const observer = {
case PurchasedState.SESSION_EXPIRED:
store.dispatch(Actions.purchaseExpired())
break
case PurchasedState.OUT_OF_CREDENTIALS:
store.dispatch(Actions.outOfCredentials())
break
case PurchasedState.FAILED:
store.dispatch(Actions.purchaseFailed({
state: PurchasedState.FAILED, stateDescription: description
Expand Down

0 comments on commit 6d954aa

Please sign in to comment.