77
88import fs from 'node:fs' ;
99import got from 'got' ;
10- import { CookieJar } from 'tough-cookie' ;
1110import FormData from 'form-data' ;
1211import { SfError , Logger } from '@salesforce/core' ;
1312
1413export type SeedResponse = {
1514 request_id : string ;
1615} ;
16+ export type ServletResponse = {
17+ jwt : string ;
18+ } ;
19+ export type AuthServletResponse = {
20+ statusCode : string ;
21+ body : string ;
22+ } ;
1723
1824export type PollSeedResponse = {
1925 execution_end_time : string ;
@@ -26,41 +32,36 @@ export type PollSeedResponse = {
2632
2733export type DataSeedingOperation = 'data-generation' | 'data-copy' ;
2834
29- const baseUrl = process . env . SF_DATA_SEEDING_URL ?? 'https://data-seed-scratchpad5.sfdc-3vx9f4.svc.sfdcfc.net' ;
30- const csrfUrl = `${ baseUrl } /get-csrf-token` ;
35+ const baseUrl = 'https://api.salesforce.com/platform/data-seed/v1' ;
3136const seedUrl = `${ baseUrl } /data-seed` ;
3237const pollUrl = `${ baseUrl } /status` ;
33-
34- export const getCookieJar = async ( ) : Promise < CookieJar > => {
35- const cookieJar = new CookieJar ( ) ;
36- await got ( csrfUrl , { cookieJar } ) ;
37- return cookieJar ;
38- } ;
39-
40- export const getCsrfToken = ( cookieJar : CookieJar ) : string => {
41- const csrfToken = cookieJar . getCookiesSync ( csrfUrl ) . find ( ( cookie ) => cookie . key === 'csrf_token' ) ?. value ;
42- if ( ! csrfToken ) throw new SfError ( 'Failed to obtain CSRF token' ) ;
43-
44- return csrfToken ;
45- } ;
46-
47- export const initiateDataSeed = async ( config : string , operation : DataSeedingOperation ) : Promise < SeedResponse > => {
48- const cookieJar = await getCookieJar ( ) ;
49- const csrf = getCsrfToken ( cookieJar ) ;
50-
38+ const sfRegion = 'us-east-1'
39+ export const initiateDataSeed = async (
40+ config : string ,
41+ operation : DataSeedingOperation ,
42+ jwt : string ,
43+ srcOrgUrl : string ,
44+ srcAccessToken : string ,
45+ tgtOrgUrl : string ,
46+ tgtAccessToken : string ,
47+ srcOrgId : string
48+ ) : Promise < SeedResponse > => {
5149 const form = new FormData ( ) ;
5250 form . append ( 'config_file' , fs . createReadStream ( config ) ) ;
53- form . append ( 'credentials_file' , fs . createReadStream ( 'ignore/credentials.txt' ) ) ;
5451 form . append ( 'operation' , operation ) ;
55-
52+ form . append ( 'source_access_token' , srcAccessToken ) ;
53+ form . append ( 'source_instance_url' , srcOrgUrl ) ;
54+ form . append ( 'target_access_token' , tgtAccessToken ) ;
55+ form . append ( 'target_instance_url' , tgtOrgUrl ) ;
56+ form . append ( 'source_org_id' , srcOrgId ) ;
5657 // TODO: Update to use .json() instead of JSON.parse once the Error response is changed to be JSON
5758 // Update the return type as well
5859 const response = await got . post ( seedUrl , {
5960 throwHttpErrors : false ,
60- cookieJar,
6161 headers : {
6262 ...form . getHeaders ( ) ,
63- 'X-CSRFToken' : csrf ,
63+ Authorization : `Bearer ${ jwt } ` ,
64+ 'x-salesforce-region' :sfRegion ,
6465 } ,
6566 body : form ,
6667 } ) ;
@@ -72,12 +73,56 @@ export const initiateDataSeed = async (config: string, operation: DataSeedingOpe
7273 return JSON . parse ( response . body ) as SeedResponse ;
7374} ;
7475
75- export const pollSeedStatus = async ( jobId : string ) : Promise < PollSeedResponse > => {
76+ export const initiateJWTMint = async (
77+ srcOrgUrl : string ,
78+ srcAccessToken : string ,
79+ tgtOrgUrl : string ,
80+ tgtAccessToken : string
81+ ) : Promise < ServletResponse > => {
82+ const srcServletUrl = `${ srcOrgUrl } /dataseed/auth` ;
83+ const tgtServletUrl = `${ tgtOrgUrl } /dataseed/auth` ;
84+
85+ const [ responseSrc , responseTgt ] = await Promise . all ( [
86+ callAuthServlet ( srcServletUrl , srcAccessToken ) ,
87+ callAuthServlet ( tgtServletUrl , tgtAccessToken ) ,
88+ ] ) ;
89+
90+ if ( responseSrc . statusCode === '200' ) {
91+ return JSON . parse ( responseSrc . body ) as ServletResponse ;
92+ }
93+
94+ if ( responseTgt . statusCode === '200' ) {
95+ return JSON . parse ( responseTgt . body ) as ServletResponse ;
96+ }
97+
98+ throw new SfError (
99+ `Org permission for data seed not found in either the source or target org.\nSource Response: Error Code : ${ responseSrc . statusCode } - ${ responseSrc . body } . \nTarget Response: Error Code : ${ responseTgt . statusCode } - ${ responseTgt . body } `
100+ ) ;
101+ } ;
102+
103+ const callAuthServlet = async ( url : string , accessToken : string ) : Promise < AuthServletResponse > => {
104+ const response = await got . post ( url , {
105+ throwHttpErrors : false ,
106+ headers : {
107+ Authorization : `Bearer ${ accessToken } ` ,
108+ } ,
109+ } ) ;
110+ return {
111+ statusCode : response . statusCode . toString ( ) , // Convert to string
112+ body : response . body ,
113+ } ;
114+ } ;
115+
116+ export const pollSeedStatus = async ( jobId : string , jwt : string ) : Promise < PollSeedResponse > => {
76117 const logger = await Logger . child ( 'PollSeedStatus' ) ;
77118
78119 // TODO: Update to use .json() instead of JSON.parse once the Error response is changed to be JSON
79120 // Update the return type as well
80- const response = await got . get ( `${ pollUrl } /${ jobId } ` , { throwHttpErrors : false } ) ;
121+ const headers = {
122+ Authorization : `Bearer ${ jwt } ` ,
123+ 'x-salesforce-region' : sfRegion ,
124+ } ;
125+ const response = await got . get ( `${ pollUrl } /${ jobId } ` , { throwHttpErrors : false , headers } ) ;
81126
82127 if ( response . statusCode !== 200 ) {
83128 // TODO: Print error body once the Error response is changed to be JSON
0 commit comments