UNPKG

9.52 kBJavaScriptView Raw
1"use strict";
2/*
3 * Copyright (c) 2021, salesforce.com, inc.
4 * All rights reserved.
5 * Licensed under the BSD 3-Clause license.
6 * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7 */
8Object.defineProperty(exports, "__esModule", { value: true });
9exports.SfdcUrl = exports.getLoginAudienceCombos = void 0;
10const url_1 = require("url");
11const kit_1 = require("@salesforce/kit");
12const ts_types_1 = require("@salesforce/ts-types");
13const myDomainResolver_1 = require("../status/myDomainResolver");
14const logger_1 = require("../logger");
15const lifecycleEvents_1 = require("../lifecycleEvents");
16function getLoginAudienceCombos(audienceUrl, loginUrl) {
17 const filtered = [
18 [loginUrl, loginUrl],
19 [SfdcUrl.SANDBOX, SfdcUrl.SANDBOX],
20 [SfdcUrl.PRODUCTION, SfdcUrl.PRODUCTION],
21 [audienceUrl, audienceUrl],
22 [audienceUrl, SfdcUrl.PRODUCTION],
23 [audienceUrl, SfdcUrl.SANDBOX],
24 [loginUrl, audienceUrl],
25 [loginUrl, SfdcUrl.PRODUCTION],
26 [loginUrl, SfdcUrl.SANDBOX],
27 [SfdcUrl.PRODUCTION, audienceUrl],
28 [SfdcUrl.SANDBOX, audienceUrl],
29 ].filter(([login, audience]) => !((login === SfdcUrl.PRODUCTION && audience === SfdcUrl.SANDBOX) ||
30 (login === SfdcUrl.SANDBOX && audience === SfdcUrl.PRODUCTION)));
31 const reduced = filtered.reduce((acc, [login, audience]) => {
32 const l = new url_1.URL(login);
33 const a = new url_1.URL(audience);
34 acc.set(`${l.origin}:${a.origin}`, [login, audience]);
35 return acc;
36 }, new Map());
37 return [...reduced.values()];
38}
39exports.getLoginAudienceCombos = getLoginAudienceCombos;
40class SfdcUrl extends url_1.URL {
41 constructor(input, base) {
42 super(input.toString(), base);
43 if (this.protocol !== 'https:' && !SfdcUrl.cache.has(this.origin)) {
44 SfdcUrl.cache.add(this.origin);
45 void lifecycleEvents_1.Lifecycle.getInstance().emitWarning(`Using insecure protocol: ${this.protocol} on url: ${this.origin}`);
46 }
47 }
48 static isValidUrl(input) {
49 try {
50 new url_1.URL(input.toString());
51 return true;
52 }
53 catch {
54 return false;
55 }
56 }
57 /**
58 * Returns the appropriate jwt audience url for this url
59 * Use SFDX_AUDIENCE_URL env var to override the audience url
60 *
61 * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
62 * @return {Promise<string>} The audience url
63 */
64 async getJwtAudienceUrl(createdOrgInstance) {
65 this.logger = await logger_1.Logger.child('SfdcUrl');
66 // environment variable is used as an override
67 const envVarVal = new kit_1.Env().getString('SFDX_AUDIENCE_URL', '');
68 if (envVarVal) {
69 this.logger.debug(`Audience URL overridden by env var SFDX_AUDIENCE_URL=${envVarVal}`);
70 return envVarVal;
71 }
72 if ((createdOrgInstance && /^gs1/gi.test(createdOrgInstance)) || /(gs1.my.salesforce.com)/gi.test(this.origin)) {
73 return 'https://gs1.salesforce.com';
74 }
75 return SfdcUrl.PRODUCTION;
76 }
77 /**
78 * Tests whether this url contains a Salesforce owned domain
79 *
80 * @return {boolean} true if this is a salesforce domain
81 */
82 isSalesforceDomain() {
83 // Source https://help.salesforce.com/articleView?id=000003652&type=1
84 const allowlistOfSalesforceDomainPatterns = [
85 '.cloudforce.com',
86 '.content.force.com',
87 '.force.com',
88 '.salesforce.com',
89 '.salesforceliveagent.com',
90 '.secure.force.com',
91 'crmforce.mil',
92 ];
93 const allowlistOfSalesforceHosts = ['developer.salesforce.com', 'trailhead.salesforce.com'];
94 return allowlistOfSalesforceDomainPatterns.some((pattern) => {
95 return this.hostname.endsWith(pattern) || allowlistOfSalesforceHosts.includes(this.hostname);
96 });
97 }
98 /**
99 * Tests whether this url is an internal Salesforce domain
100 *
101 * @returns {boolean} true if this is an internal domain
102 */
103 isInternalUrl() {
104 const INTERNAL_URL_PARTS = [
105 '.vpod.',
106 'stm.salesforce.com',
107 'stm.force.com',
108 '.blitz.salesforce.com',
109 '.stm.salesforce.ms',
110 '.pc-rnd.force.com',
111 '.pc-rnd.salesforce.com',
112 ];
113 return (this.origin.startsWith('https://gs1.') ||
114 this.isLocalUrl() ||
115 INTERNAL_URL_PARTS.some((part) => this.origin.includes(part)));
116 }
117 /**
118 * Tests whether this url runs on a local machine
119 *
120 * @returns {boolean} true if this is a local machine
121 */
122 isLocalUrl() {
123 const LOCAL_PARTS = ['localhost.sfdcdev.', '.internal.'];
124 return LOCAL_PARTS.some((part) => this.origin.includes(part));
125 }
126 toLightningDomain() {
127 if (this.origin.endsWith('.my.salesforce.mil')) {
128 return this.origin.replace('.my.salesforce.mil', '.lightning.crmforce.mil');
129 }
130 // enhanced domains
131 // ex: sandbox.my.salesforce.com, scratch.my.salesforce.com, etc
132 if (this.origin.endsWith('.my.salesforce.com')) {
133 return this.origin.replace('.my.salesforce.com', '.lightning.force.com');
134 }
135 // alternative domains
136 if (this.origin.endsWith('.my-salesforce.com')) {
137 return this.origin.replace('.my-salesforce.com', '.my-lightning.com');
138 }
139 // all non-mil domains
140 return `https://${(0, ts_types_1.ensureArray)(/https?:\/\/([^.]*)/.exec(this.origin))
141 .slice(1, 2)
142 .pop()}.lightning.force.com`;
143 }
144 /**
145 * Tests whether this url has the lightning domain extension
146 * This method that performs the dns lookup of the host. If the lookup fails the internal polling (1 second), client will try again until timeout
147 * If SFDX_DOMAIN_RETRY environment variable is set (number) it overrides the default timeout duration (240 seconds)
148 *
149 * @returns {Promise<true | never>} The resolved ip address or never
150 * @throws {@link SfError} If can't resolve DNS.
151 */
152 async checkLightningDomain() {
153 const quantity = (0, ts_types_1.ensureNumber)(new kit_1.Env().getNumber('SFDX_DOMAIN_RETRY', 240));
154 const timeout = new kit_1.Duration(quantity, kit_1.Duration.Unit.SECONDS);
155 if (this.isInternalUrl() || timeout.seconds === 0) {
156 return true;
157 }
158 const resolver = await myDomainResolver_1.MyDomainResolver.create({
159 url: new url_1.URL(this.toLightningDomain()),
160 timeout,
161 frequency: new kit_1.Duration(1, kit_1.Duration.Unit.SECONDS),
162 });
163 await resolver.resolve();
164 return true;
165 }
166 /**
167 * Method that performs the dns lookup of the host. If the lookup fails the internal polling (1 second), client will try again until timeout
168 * If SFDX_DOMAIN_RETRY environment variable is set (number) it overrides the default timeout duration (240 seconds)
169 *
170 * @returns the resolved ip address.
171 * @throws {@link SfError} If can't resolve DNS.
172 */
173 async lookup() {
174 const quantity = (0, ts_types_1.ensureNumber)(new kit_1.Env().getNumber('SFDX_DOMAIN_RETRY', 240));
175 const timeout = new kit_1.Duration(quantity, kit_1.Duration.Unit.SECONDS);
176 const resolver = await myDomainResolver_1.MyDomainResolver.create({
177 url: new url_1.URL(this.origin),
178 timeout,
179 frequency: new kit_1.Duration(1, kit_1.Duration.Unit.SECONDS),
180 });
181 return resolver.resolve();
182 }
183 /**
184 * Tests whether this url is a sandbox url
185 *
186 * @Deprecated - identification of a sandbox instance by URL alone is not deterministic
187 * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
188 * @returns {boolean}
189 */
190 // TODO: how to get rid of this?
191 isSandboxUrl(createdOrgInstance) {
192 return ((createdOrgInstance && /^cs|s$/gi.test(createdOrgInstance)) ||
193 this.origin.endsWith('sandbox.my.salesforce.mil') ||
194 /sandbox\.my\.salesforce\.com/gi.test(this.origin) || // enhanced domains >= 230
195 /(cs[0-9]+(\.my|)\.salesforce\.com)/gi.test(this.origin) || // my domains on CS instance OR CS instance without my domain
196 /(cs[0-9]+\.force\.com)/gi.test(this.origin) || // sandboxes have cnames like cs123.force.com
197 /(\w+--\w+\.my\.salesforce\.com)/gi.test(this.origin) || // sandboxes myDomain like foo--bar.my.salesforce.com
198 /([a-z]{3}[0-9]+s\.sfdc-.+\.salesforce\.com)/gi.test(this.origin) || // falcon sandbox ex: usa2s.sfdc-whatever.salesforce.com
199 /([a-z]{3}[0-9]+s\.sfdc-.+\.force\.com)/gi.test(this.origin) || // falcon sandbox ex: usa2s.sfdc-whatever.force.com
200 this.hostname === 'test.salesforce.com');
201 }
202 /**
203 * Test whether this url represents a lightning domain
204 *
205 * @returns {boolean} true if this domain is a lightning domain
206 */
207 isLightningDomain() {
208 return /\.lightning\.force\.com/.test(this.origin) || /\.lightning\.crmforce\.mil/.test(this.origin);
209 }
210}
211exports.SfdcUrl = SfdcUrl;
212/**
213 * Salesforce URLs
214 */
215SfdcUrl.SANDBOX = 'https://test.salesforce.com';
216SfdcUrl.PRODUCTION = 'https://login.salesforce.com';
217SfdcUrl.cache = new Set();
218//# sourceMappingURL=sfdcUrl.js.map
\No newline at end of file