Skip to content

Commit 50b0e7e

Browse files
committed
fix: authentication
1 parent 02c1707 commit 50b0e7e

File tree

4 files changed

+159
-1
lines changed

4 files changed

+159
-1
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@salesforce/sf-plugins-core": "^11.2.4",
1616
"@inquirer/select": "^2.4.7",
1717
"@inquirer/prompts": "^5.3.8",
18+
"axios": "^1.7.7",
1819
"chalk": "^5.3.0",
1920
"lwc": "7.1.3",
2021
"lwr": "0.14.2",

src/commands/lightning/dev/site.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,12 @@ export default class LightningDevSite extends SfCommand<void> {
6767
// Pass the org auth token so LWR can make authenticated requests to core
6868
const authToken = org.getConnection().accessToken ?? '';
6969

70+
const networkId = await selectedSite.getNetworkIdByName();
71+
const sidToken = await selectedSite.getNewSidToken(networkId);
72+
7073
// Start the dev server
7174
await expDev({
72-
authToken,
75+
authToken: sidToken || authToken,
7376
open: true,
7477
port: 3000,
7578
logLevel: 'error',

src/shared/experience/expSite.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import fs from 'node:fs';
88
import path from 'node:path';
99
import { Org, SfError } from '@salesforce/core';
10+
import axios from 'axios';
1011

1112
export type SiteMetadata = {
1213
bundleName: string;
@@ -225,6 +226,140 @@ export class ExperienceSite {
225226

226227
return resourcePath;
227228
}
229+
230+
// TODO cleanup
231+
public async getNetworkIdByName(): Promise<string> {
232+
const conn = this.org.getConnection();
233+
// try {
234+
// Query the Network object for the network with the given site name
235+
const result = await conn.query<{ Id: string }>(`SELECT Id FROM Network WHERE Name = '${this.siteDisplayName}'`);
236+
237+
const record = result.records[0];
238+
if (record) {
239+
let networkId = record.Id;
240+
// Subtract the last three characters from the Network ID
241+
networkId = networkId.substring(0, networkId.length - 3);
242+
return networkId;
243+
} else {
244+
throw new Error(`Network with name '${this.siteDisplayName}' not found`);
245+
}
246+
// } catch (error) {
247+
// // console.error('Error fetching Network ID:', error);
248+
// throw error;
249+
// }
250+
}
251+
252+
public async getNewSidToken(networkId: string): Promise<string> {
253+
// Get the connection and access token from the org
254+
const conn = this.org.getConnection();
255+
const identity = await conn.identity();
256+
if (identity.user_id) {
257+
// do something
258+
}
259+
const orgId = this.org.getOrgId();
260+
const orgIdMinus3 = orgId.substring(0, orgId.length - 3);
261+
const accessToken = conn.accessToken;
262+
const instanceUrl = conn.instanceUrl;
263+
264+
// Construct the switch URL
265+
const switchUrl = `${instanceUrl}/servlet/networks/switch?networkId=${networkId}`;
266+
267+
// try {
268+
// Make the GET request without following redirects
269+
if (accessToken) {
270+
const cookies = [
271+
`sid=${accessToken}`,
272+
`oid=${orgIdMinus3}`,
273+
// 'sid_Client=s000000uuCPw000000I7xV',
274+
// Include other essential cookies if necessary
275+
// For example:
276+
// `oid=${conn.getAuthInfoFields().orgId}`,
277+
// `sid_Client=${conn.userInfo.id}`,
278+
// Add any other cookies that might be required
279+
]
280+
.join('; ')
281+
.trim();
282+
let response = await axios.get(switchUrl, {
283+
headers: {
284+
Cookie: cookies,
285+
// Include other headers if necessary
286+
// 'User-Agent': 'Your User Agent String',
287+
// 'Referer': 'Referer URL if required',
288+
},
289+
withCredentials: true,
290+
maxRedirects: 0, // Prevent axios from following redirects
291+
validateStatus: (status) => status >= 200 && status < 400, // Accept 3xx status codes
292+
});
293+
294+
// Extract the Location header
295+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
296+
const locationHeader = response.headers['location'];
297+
298+
if (locationHeader) {
299+
// Parse the URL to extract the 'sid' parameter
300+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
301+
const urlObj = new URL(locationHeader);
302+
const sid = urlObj.searchParams.get('sid') ?? '';
303+
const cookies2 = [
304+
'__Secure-has-sid=1',
305+
`sid=${sid}`,
306+
`oid=${orgIdMinus3}`,
307+
// 'sid_Client=s000000uuCPw000000I7xV',
308+
// Include other essential cookies if necessary
309+
// For example:
310+
// `oid=${conn.getAuthInfoFields().orgId}`,
311+
// `sid_Client=${conn.userInfo.id}`,
312+
// Add any other cookies that might be required
313+
]
314+
.join('; ')
315+
.trim();
316+
317+
response = await axios.get(urlObj.toString(), {
318+
headers: {
319+
Cookie: cookies2,
320+
// Include other headers if necessary
321+
// 'User-Agent': 'Your User Agent String',
322+
// 'Referer': 'Referer URL if required',
323+
},
324+
withCredentials: true,
325+
maxRedirects: 0, // Prevent axios from following redirects
326+
validateStatus: (status) => status >= 200 && status < 400, // Accept 3xx status codes
327+
});
328+
const setCookieHeader = response.headers['set-cookie'];
329+
if (setCookieHeader) {
330+
// 'set-cookie' can be an array if multiple cookies are set
331+
// Find the 'sid' cookie in the set-cookie header
332+
const sidCookie = setCookieHeader.find((cookieStr: string) => cookieStr.startsWith('sid='));
333+
334+
if (sidCookie) {
335+
// Extract the sid value from the cookie string
336+
const sidMatch = sidCookie.match(/sid=([^;]+)/);
337+
if (sidMatch?.[1]) {
338+
const sidToken = sidMatch[1];
339+
return sidToken;
340+
}
341+
}
342+
} else {
343+
// eslint-disable-next-line no-console
344+
console.log('error couldnt find set-cookie header for sid token');
345+
}
346+
347+
if (sid) {
348+
return sid;
349+
} else {
350+
throw new Error('SID token not found in Location header');
351+
}
352+
} else {
353+
throw new Error('Location header not found in response');
354+
}
355+
}
356+
return '';
357+
// } catch (error) {
358+
// // Handle errors (e.g., network issues, HTTP errors)
359+
// // console.error('Error obtaining new SID token:', error);
360+
// throw error;
361+
// }
362+
}
228363
}
229364

230365
/**

yarn.lock

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6126,6 +6126,15 @@ axe-core@^4.6.2:
61266126
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59"
61276127
integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==
61286128

6129+
axios@^1.7.7:
6130+
version "1.7.7"
6131+
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
6132+
integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
6133+
dependencies:
6134+
follow-redirects "^1.15.6"
6135+
form-data "^4.0.0"
6136+
proxy-from-env "^1.1.0"
6137+
61296138
axobject-query@^3.1.1:
61306139
version "3.2.4"
61316140
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.4.tgz#6dfba930294ea14d7d2fc68b9d007211baedb94c"
@@ -8695,6 +8704,11 @@ follow-redirects@^1.0.0:
86958704
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
86968705
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
86978706

8707+
follow-redirects@^1.15.6:
8708+
version "1.15.9"
8709+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
8710+
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
8711+
86988712
for-each@^0.3.3:
86998713
version "0.3.3"
87008714
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
@@ -12991,6 +13005,11 @@ proxy-addr@~2.0.7:
1299113005
forwarded "0.2.0"
1299213006
ipaddr.js "1.9.1"
1299313007

13008+
proxy-from-env@^1.1.0:
13009+
version "1.1.0"
13010+
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
13011+
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
13012+
1299413013
psl@^1.1.33:
1299513014
version "1.9.0"
1299613015
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"

0 commit comments

Comments
 (0)