Skip to content

Commit 7ca61f0

Browse files
committed
use backend api domain for forwarder. AG-32237
Squashed commit of the following: commit 942c2dd Author: Slava Leleka <[email protected]> Date: Fri Apr 26 14:39:30 2024 +0400 fix typo commit c0b0229 Author: Slava Leleka <[email protected]> Date: Fri Apr 26 14:22:04 2024 +0400 make sure extension uninstall url is set commit b9dab67 Author: Slava Leleka <[email protected]> Date: Fri Apr 26 14:18:16 2024 +0400 Revert "remove obsolete uninstall script" This reverts commit 260abeb. commit 260abeb Author: Slava Leleka <[email protected]> Date: Fri Apr 26 14:15:17 2024 +0400 remove obsolete uninstall script commit cb67ba4 Author: Slava Leleka <[email protected]> Date: Fri Apr 26 13:51:08 2024 +0400 add test for fallback api update commit 1530ab3 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 21:21:55 2024 +0400 cleanup commit 610ad5a Author: Slava Leleka <[email protected]> Date: Thu Apr 25 21:02:49 2024 +0400 improve fallbackApi commit a1d9fc4 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:57:30 2024 +0400 simplify uninstall url setting commit 2f24d1b Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:48:45 2024 +0400 refactor helpers commit 36ffbfe Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:42:14 2024 +0400 fix linter commit 3fbd717 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:40:36 2024 +0400 improve fallbackApi commit 2761dff Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:40:25 2024 +0400 fix tests commit f825504 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 20:40:11 2024 +0400 move forwarder to background dir commit f2da809 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 18:20:25 2024 +0400 cleanup, improve uninstall url setting commit ad97bfa Author: Slava Leleka <[email protected]> Date: Thu Apr 25 17:39:25 2024 +0400 simplify forwarder class commit cb22643 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 14:03:40 2024 +0400 ditch init sleep for uninstall script commit 65c0b62 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 13:58:51 2024 +0400 fix getForwarderApiUrl comment commit 04c0d35 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 13:55:19 2024 +0400 ditch Forwarder.prevDomain commit b4d3395 Author: Slava Leleka <[email protected]> Date: Thu Apr 25 00:05:46 2024 +0400 cleanup, improve Forwarder.getUrl() comment commit 5500fd7 Author: Slava Leleka <[email protected]> Date: Wed Apr 24 23:23:31 2024 +0400 force fallback info updating after ff permission is grangted ... and 15 more commits
1 parent 94336fc commit 7ca61f0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+715
-209
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- @adguard/logger library for logging
1313

14+
### Changed
15+
16+
- Backend API domain is used for forwarder urls.
17+
18+
[Unreleased]: https://github.com/AdguardTeam/AdGuardVPNExtension/compare/v2.2.14...HEAD
19+
1420

1521
## [2.2.14] - 2024-03-15
1622

src/background/actions.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import browser from 'webextension-polyfill';
33
import { Prefs } from '../common/prefs';
44
import { log } from '../common/logger';
55
import { SETTINGS_IDS, THEME_URL_PARAMETER } from '../common/constants';
6+
import { getForwarderUrl } from '../common/helpers';
67

78
import { tabs } from './tabs';
89
import { credentials } from './credentials';
10+
import { forwarder } from './forwarder';
911
import { settings } from './settings';
10-
import { UPGRADE_LICENSE_URL } from './config';
12+
import { FORWARDER_URL_QUERIES } from './config';
1113
import { promoNotifications } from './promoNotifications';
1214
import { browserAction } from './browserAction';
1315

@@ -208,7 +210,9 @@ const clearBadgeText = async (tabId: number) => {
208210
*/
209211
const getPremiumPromoPageUrl = async (): Promise<string> => {
210212
const username = await credentials.getUsername();
211-
return `${UPGRADE_LICENSE_URL}${username ? `&email=${encodeURIComponent(username)}` : ''}`;
213+
const forwarderDomain = await forwarder.updateAndGetDomain();
214+
const upgradeLicenseUrl = getForwarderUrl(forwarderDomain, FORWARDER_URL_QUERIES.UPGRADE_LICENSE);
215+
return `${upgradeLicenseUrl}${username ? `&email=${encodeURIComponent(username)}` : ''}`;
212216
};
213217

214218
/**

src/background/api/fallbackApi.ts

+43-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
AUTH_API_URL,
77
VPN_API_URL,
88
STAGE_ENV,
9+
FORWARDER_DOMAIN,
910
} from '../config';
1011
import { clearFromWrappingQuotes } from '../../common/utils/string';
1112
import { log } from '../../common/logger';
@@ -16,8 +17,6 @@ import { authService } from '../authentication/authService';
1617
import { credentialsService } from '../credentials/credentialsService';
1718
import { FallbackInfo, StorageKey } from '../schema';
1819

19-
export const DEFAULT_CACHE_EXPIRE_TIME_MS = 1000 * 60 * 5; // 5 minutes
20-
2120
// DNS over https api
2221
const GOOGLE_DOH_HOSTNAME = 'dns.google';
2322
export const GOOGLE_DOH_URL = `${GOOGLE_DOH_HOSTNAME}/resolve`;
@@ -54,14 +53,20 @@ export class FallbackApi {
5453
*/
5554
defaultFallbackInfo: FallbackInfo;
5655

56+
/**
57+
* Fallback info cache expiration time in milliseconds.
58+
*/
59+
static DEFAULT_CACHE_EXPIRE_TIME_MS = 1000 * 60 * 5; // 5 minutes
60+
5761
/**
5862
* Default urls we set already expired,
5963
* so we need to check bkp url immediately when bkp url is required
6064
*/
61-
constructor(vpnApiUrl: string, authApiUrl: string) {
65+
constructor(vpnApiUrl: string, authApiUrl: string, forwarderApiUrl: string) {
6266
this.defaultFallbackInfo = {
6367
vpnApiUrl,
6468
authApiUrl,
69+
forwarderApiUrl,
6570
expiresInMs: Date.now() - 1,
6671
};
6772
}
@@ -84,7 +89,11 @@ export class FallbackApi {
8489
return fallbackInfo.expiresInMs < Date.now();
8590
}
8691

87-
private async updateFallbackInfo() {
92+
/**
93+
* Updates the fallback info.
94+
* If backup urls are not received, the default fallback info is set.
95+
*/
96+
private async updateFallbackInfo(): Promise<void> {
8897
const [bkpVpnApiUrl, bkpAuthApiUrl] = await Promise.all([
8998
this.getBkpVpnApiUrl(),
9099
this.getBkpAuthApiUrl(),
@@ -94,8 +103,13 @@ export class FallbackApi {
94103
this.fallbackInfo = {
95104
vpnApiUrl: bkpVpnApiUrl,
96105
authApiUrl: bkpAuthApiUrl,
97-
expiresInMs: Date.now() + DEFAULT_CACHE_EXPIRE_TIME_MS,
106+
// use received vpn api url as forwarder api url
107+
forwarderApiUrl: bkpVpnApiUrl,
108+
expiresInMs: Date.now() + FallbackApi.DEFAULT_CACHE_EXPIRE_TIME_MS,
98109
};
110+
} else if (!this.fallbackInfo) {
111+
// set default fallback info if bkp urls are not received and fallback info is not set
112+
this.fallbackInfo = this.defaultFallbackInfo;
99113
}
100114
}
101115

@@ -115,6 +129,21 @@ export class FallbackApi {
115129
return fallbackInfo.vpnApiUrl;
116130
};
117131

132+
/**
133+
* Returns fallback forwarder API URL. AG-32237.
134+
*
135+
* Received VPN API URL is used as a fallback forwarder API URL,
136+
* but if the default VPN API URL is received, the default forwarder API URL should be returned.
137+
*
138+
* @returns Forwarder API URL.
139+
*/
140+
public getForwarderApiUrl = async (): Promise<string> => {
141+
const { forwarderApiUrl } = await this.getFallbackInfo();
142+
return forwarderApiUrl === this.defaultFallbackInfo.vpnApiUrl
143+
? this.defaultFallbackInfo.forwarderApiUrl
144+
: forwarderApiUrl;
145+
};
146+
118147
public getAuthApiUrl = async (): Promise<string> => {
119148
const fallbackInfo = await this.getFallbackInfo();
120149
return fallbackInfo.authApiUrl;
@@ -284,7 +313,14 @@ export class FallbackApi {
284313
return `${basePrefix}.${UserType.Free}`;
285314
};
286315

287-
getBkpVpnApiUrl = async () => {
316+
/**
317+
* Fetches and returns backup VPN API URL.
318+
*
319+
* @returns Backup VPN API URL if fetched successfully and not an empty string;
320+
* if fetched url is an empty string, returns default fallback VPN API URL;
321+
* OR null if fetching failed.
322+
*/
323+
getBkpVpnApiUrl = async (): Promise<string | null> => {
288324
const prefix = await this.getApiHostnamePrefix();
289325
// we use prefix for api hostname to recognize free, premium and not authenticated users
290326
const hostname = `${prefix}.${BKP_API_HOSTNAME_PART}`;
@@ -313,4 +349,4 @@ export class FallbackApi {
313349
}
314350
}
315351

316-
export const fallbackApi = new FallbackApi(VPN_API_URL, AUTH_API_URL);
352+
export const fallbackApi = new FallbackApi(VPN_API_URL, AUTH_API_URL, FORWARDER_DOMAIN);

src/background/config.ts

+110-22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,42 @@ import { log } from '../common/logger';
22

33
import { runtime } from './browserApi/runtime';
44

5+
/**
6+
* Keys for forwarder urls queries.
7+
*/
8+
const enum ForwarderUrlQueryKey {
9+
AdguardDnsKb = 'ADGUARD_DNS_KB',
10+
ComparePage = 'COMPARE_PAGE',
11+
DeviceCount = 'DEVICE_COUNT',
12+
EditAccount = 'EDIT_ACCOUNT',
13+
Eula = 'EULA',
14+
Faq = 'FAQ',
15+
Feedback = 'FEEDBACK',
16+
FirefoxThankYouPage = 'FIREFOX_THANK_YOU_PAGE',
17+
OptionsStore = 'OPTIONS_STORE',
18+
OtherProducts = 'OTHER_PRODUCTS',
19+
PasswordCompromised = 'PASSWORD_COMPROMISED',
20+
PasswordRecovery = 'PASSWORD_RECOVERY',
21+
PopupDefaultSupport = 'POPUP_DEFAULT_SUPPORT',
22+
PopupFeedback = 'POPUP_FEEDBACK',
23+
PopupStore = 'POPUP_STORE',
24+
Privacy = 'PRIVACY',
25+
Subscribe = 'SUBSCRIBE',
26+
SuggestFeature = 'SUGGEST_FEATURE',
27+
ThankYouPage = 'THANK_YOU_PAGE',
28+
UninstallPage = 'UNINSTALL_PAGE',
29+
UpgradeLicense = 'UPGRADE_LICENSE',
30+
VpnBlockedGetApp = 'VPN_BLOCKED_GET_APP',
31+
Website = 'WEBSITE',
32+
}
33+
34+
/**
35+
* Type for forwarder urls queries data object.
36+
*/
37+
type ForwarderUrlQueries = {
38+
[key in ForwarderUrlQueryKey]: string;
39+
};
40+
541
// global data
642
// @ts-ignore
743
const CONFIG = __APP_CONFIG__;
@@ -16,37 +52,89 @@ log.debug(`Current stage env: "${CONFIG.STAGE_ENV}"`);
1652

1753
Object.keys(CONFIG).forEach((key) => {
1854
if (CONFIG[key] === undefined) {
19-
throw new Error(`All values in config should be defined, ${CONFIG}`);
55+
throw new Error(`Missed value for key '${key}' in config: ${CONFIG}`);
2056
}
2157
});
2258

23-
export const {
59+
const {
2460
VPN_API_URL,
2561
AUTH_API_URL,
26-
PASSWORD_RECOVERY_URL,
27-
EDIT_ACCOUNT_URL,
2862
AUTH_CLIENT_ID,
29-
POPUP_STORE_URL,
30-
POPUP_FEEDBACK_URL,
31-
OPTIONS_STORE_URL,
3263
WS_API_URL_TEMPLATE,
33-
PRIVACY_URL,
34-
EULA_URL,
35-
UPGRADE_LICENSE_URL,
36-
OTHER_PRODUCTS_URL,
37-
POPUP_DEFAULT_SUPPORT_URL,
38-
WEBSITE_URL,
39-
ADGUARD_DNS_KB_LINK,
40-
FORWARDER_DOMAIN,
41-
SUGGEST_FEATURE,
42-
THANK_YOU_PAGE_URL,
43-
FIREFOX_THANK_YOU_PAGE_URL,
44-
UNINSTALL_PAGE_URL,
45-
FEEDBACK_URL,
46-
FAQ_URL,
4764
BROWSER,
4865
BUILD_ENV,
4966
STAGE_ENV,
67+
// keep them sorted
68+
ADGUARD_DNS_KB,
5069
COMPARE_PAGE,
51-
VPN_BLOCKED_GET_APP_LINK,
70+
DEVICE_COUNT,
71+
EDIT_ACCOUNT,
72+
EULA,
73+
FAQ,
74+
FEEDBACK,
75+
FIREFOX_THANK_YOU_PAGE,
76+
OPTIONS_STORE,
77+
OTHER_PRODUCTS,
78+
PASSWORD_COMPROMISED,
79+
PASSWORD_RECOVERY,
80+
POPUP_DEFAULT_SUPPORT,
81+
POPUP_FEEDBACK,
82+
POPUP_STORE,
83+
PRIVACY,
84+
SUBSCRIBE,
85+
SUGGEST_FEATURE,
86+
THANK_YOU_PAGE,
87+
UNINSTALL_PAGE,
88+
UPGRADE_LICENSE,
89+
VPN_BLOCKED_GET_APP,
90+
WEBSITE,
5291
} = CONFIG;
92+
93+
// not destructuring for adding a jsdoc comment
94+
/**
95+
* **Should NOT be used directly**, use the Forwarder class. AG-32237.
96+
*/
97+
const FORWARDER_DOMAIN = CONFIG.FORWARDER_DOMAIN; // eslint-disable-line prefer-destructuring
98+
99+
/**
100+
* List of forwarder urls queries from the config.
101+
*
102+
* Needed for forwarder url generation. AG-32237.
103+
*/
104+
const FORWARDER_URL_QUERIES: ForwarderUrlQueries = {
105+
ADGUARD_DNS_KB,
106+
COMPARE_PAGE,
107+
DEVICE_COUNT,
108+
EDIT_ACCOUNT,
109+
EULA,
110+
FAQ,
111+
FEEDBACK,
112+
FIREFOX_THANK_YOU_PAGE,
113+
OPTIONS_STORE,
114+
OTHER_PRODUCTS,
115+
PASSWORD_COMPROMISED,
116+
PASSWORD_RECOVERY,
117+
POPUP_DEFAULT_SUPPORT,
118+
POPUP_FEEDBACK,
119+
POPUP_STORE,
120+
PRIVACY,
121+
SUBSCRIBE,
122+
SUGGEST_FEATURE,
123+
THANK_YOU_PAGE,
124+
UNINSTALL_PAGE,
125+
UPGRADE_LICENSE,
126+
VPN_BLOCKED_GET_APP,
127+
WEBSITE,
128+
};
129+
130+
export {
131+
VPN_API_URL,
132+
AUTH_API_URL,
133+
AUTH_CLIENT_ID,
134+
WS_API_URL_TEMPLATE,
135+
BROWSER,
136+
BUILD_ENV,
137+
STAGE_ENV,
138+
FORWARDER_DOMAIN,
139+
FORWARDER_URL_QUERIES,
140+
};

src/background/connectivity/switcher.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { proxy } from '../proxy';
22
import { log } from '../../common/logger';
3-
import { runWithCancel, sleepIfNecessary } from '../../common/helpers';
3+
import { sleepIfNecessary } from '../../common/helpers';
44
// eslint-disable-next-line import/no-cycle
55
import { credentials } from '../credentials';
66
// eslint-disable-next-line import/no-cycle
@@ -9,6 +9,7 @@ import { locationsService } from '../endpoints/locationsService';
99
import { endpoints } from '../endpoints';
1010
import type { AccessCredentialsData } from '../credentials/Credentials';
1111
import type { EndpointInterface, LocationInterface } from '../schema';
12+
import { runWithCancel } from '../helpers';
1213

1314
import {
1415
connectivityService,

src/background/endpoints/Endpoints.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import qs from 'qs';
55
import { getDomain } from 'tldts';
66

77
import { log } from '../../common/logger';
8-
import { getLocationWithLowestPing, sleep } from '../../common/helpers';
9-
import { POPUP_DEFAULT_SUPPORT_URL } from '../config';
8+
import { getForwarderUrl, getLocationWithLowestPing, sleep } from '../../common/helpers';
109
import { notifier } from '../../common/notifier';
1110
import { proxy } from '../proxy';
1211
import { vpnProvider } from '../providers/vpnProvider';
@@ -23,6 +22,8 @@ import type {
2322
import type { VpnExtensionInfoInterface } from '../../common/schema/endpoints/vpnInfo';
2423
import { settings } from '../settings';
2524
import { QuickConnectSetting } from '../../common/constants';
25+
import { forwarder } from '../forwarder';
26+
import { FORWARDER_URL_QUERIES } from '../config';
2627
import { EndpointsState, LocationInterface, StorageKey } from '../schema';
2728
import { stateStorage } from '../stateStorage';
2829

@@ -449,6 +450,8 @@ class Endpoints implements EndpointsInterface {
449450

450451
const appId = await credentials.getAppId();
451452

453+
const forwarderDomain = await forwarder.updateAndGetDomain();
454+
452455
// if no endpoints info, then get endpoints failure url with empty token
453456
let appendToQueryString = false;
454457
if (!this.vpnInfo) {
@@ -459,7 +462,7 @@ class Endpoints implements EndpointsInterface {
459462
this.vpnInfo = await vpnProvider.getVpnExtensionInfo(appId, token);
460463
} catch (e) {
461464
this.vpnInfo = {
462-
vpnFailurePage: POPUP_DEFAULT_SUPPORT_URL,
465+
vpnFailurePage: getForwarderUrl(forwarderDomain, FORWARDER_URL_QUERIES.POPUP_DEFAULT_SUPPORT),
463466
bandwidthFreeMbits: 0,
464467
premiumPromoPage: '',
465468
premiumPromoEnabled: false,

src/background/forwarder/forwarder.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { fallbackApi } from '../api/fallbackApi';
2+
import { setExtensionUninstallUrl } from '../helpers';
3+
4+
/**
5+
* Class for handling forwarder domain. AG-32237.
6+
*/
7+
export class Forwarder {
8+
/**
9+
* Domain for the forwarder.
10+
*/
11+
private domain: string;
12+
13+
/**
14+
* Updates and returns the domain for the forwarder.
15+
*
16+
* If the forwarder domain is changed, it also updates the extension uninstall url with the new domain.
17+
*
18+
* @returns Forwarder domain.
19+
*/
20+
public async updateAndGetDomain(): Promise<string> {
21+
const newDomain = await fallbackApi.getForwarderApiUrl();
22+
23+
// update the extension uninstall url if forwarder domain is changed
24+
if (newDomain !== this.domain) {
25+
this.domain = newDomain;
26+
await setExtensionUninstallUrl(this.domain);
27+
}
28+
29+
return this.domain;
30+
}
31+
}
32+
33+
export const forwarder = new Forwarder();

src/background/forwarder/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { forwarder } from './forwarder';

0 commit comments

Comments
 (0)