Skip to content

Commit 6da3f00

Browse files
committed
fix(@W-17233341): changes for minting JWT and SFAP endpoints
1 parent f762b08 commit 6da3f00

File tree

3 files changed

+74
-21
lines changed

3 files changed

+74
-21
lines changed

src/commands/data-seeding/generate/index.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
99
import { Messages, PollingClient, SfError, StatusResult } from '@salesforce/core';
1010
import { Duration } from '@salesforce/kit';
11-
import { initiateDataSeed, pollSeedStatus, PollSeedResponse } from '../../../utils/api.js';
11+
import { initiateDataSeed, pollSeedStatus, PollSeedResponse, initiateJWTMint } from '../../../utils/api.js'
1212
import { getSeedGenerateMso, getSeedGenerateStage as getStage } from '../../../utils/mso.js';
1313
import { DataSeedingGenerateResult } from '../../../utils/types.js';
1414
import { GenerateRequestCache } from '../../../utils/cache.js';
@@ -23,12 +23,12 @@ export default class DataSeedingGenerate extends SfCommand<DataSeedingGenerateRe
2323

2424
public static readonly flags = {
2525
// TODO: The org flags will need to use Flags.requiredOrg() once auth is finalized
26-
'target-org': Flags.string({
26+
'target-org': Flags.requiredOrg({
2727
summary: messages.getMessage('flags.target-org.summary'),
2828
char: 'o',
2929
required: true,
3030
}),
31-
'source-org': Flags.string({
31+
'source-org': Flags.requiredOrg({
3232
summary: messages.getMessage('flags.source-org.summary'),
3333
char: 's',
3434
required: true,
@@ -55,10 +55,20 @@ export default class DataSeedingGenerate extends SfCommand<DataSeedingGenerateRe
5555

5656
public async run(): Promise<DataSeedingGenerateResult> {
5757
const { flags } = await this.parse(DataSeedingGenerate);
58-
const { async, 'config-file': configFile, 'source-org': sourceOrg, 'target-org': targetOrg, wait } = flags;
59-
60-
const { request_id: jobId } = await initiateDataSeed(configFile, 'data-generation');
61-
58+
const { async, 'config-file': configFile, 'source-org': srcOrgObj, 'target-org': tgtOrgObj, wait } = flags;
59+
60+
const sourceOrg = srcOrgObj.getOrgId();
61+
const srcAccessToken = srcOrgObj.getConnection().accessToken as string;
62+
const srcOrgInstUrl = srcOrgObj.getConnection().instanceUrl as string;
63+
64+
const targetOrg = tgtOrgObj.getOrgId();
65+
const tgtAccessToken = tgtOrgObj.getConnection().accessToken as string;
66+
const tgtOrgInstUrl = tgtOrgObj.getConnection().instanceUrl as string;
67+
68+
//Fetch Valid JWT with Data Seed Org Perm
69+
const { jwt: jwtValue} = await initiateJWTMint(srcOrgInstUrl,srcAccessToken,tgtOrgInstUrl,tgtAccessToken );
70+
this.log("\nValid JWT Token Fetched.");
71+
const { request_id: jobId } = await initiateDataSeed(configFile, 'data-generation',jwtValue);
6272
const reportMessage = messages.getMessage('report.suggestion', [jobId]);
6373

6474
if (!jobId) throw new Error('Failed to receive job id');

src/commands/data-seeding/migrate/index.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
99
import { Duration } from '@salesforce/kit';
1010
import { Messages, PollingClient, StatusResult, SfError } from '@salesforce/core';
11-
import { initiateDataSeed, PollSeedResponse, pollSeedStatus } from '../../../utils/api.js';
11+
import { initiateDataSeed, PollSeedResponse, pollSeedStatus, initiateJWTMint } from '../../../utils/api.js';
1212
import { DataSeedingMigrateResult } from '../../../utils/types.js';
1313
import { getSeedMigrateMso, getSeedMigrateStage as getStage } from '../../../utils/mso.js';
1414
import { MigrateRequestCache } from '../../../utils/cache.js';
@@ -23,12 +23,12 @@ export default class DataSeedingMigrate extends SfCommand<DataSeedingMigrateResu
2323

2424
public static readonly flags = {
2525
// TODO: The org flags will need to use Flags.requiredOrg() once auth is finalized
26-
'target-org': Flags.string({
26+
'target-org': Flags.requiredOrg({
2727
summary: messages.getMessage('flags.target-org.summary'),
2828
char: 'o',
2929
required: true,
3030
}),
31-
'source-org': Flags.string({
31+
'source-org': Flags.requiredOrg({
3232
summary: messages.getMessage('flags.source-org.summary'),
3333
char: 's',
3434
required: true,
@@ -55,9 +55,21 @@ export default class DataSeedingMigrate extends SfCommand<DataSeedingMigrateResu
5555

5656
public async run(): Promise<DataSeedingMigrateResult> {
5757
const { flags } = await this.parse(DataSeedingMigrate);
58-
const { async, 'config-file': configFile, 'source-org': sourceOrg, 'target-org': targetOrg, wait } = flags;
59-
60-
const { request_id: jobId } = await initiateDataSeed(configFile, 'data-copy');
58+
const { async, 'config-file': configFile, 'source-org': sourceOrgObj, 'target-org': targetOrgObj, wait } = flags;
59+
60+
const sourceOrg = sourceOrgObj.getOrgId();
61+
const srcAccessToken = sourceOrgObj.getConnection().accessToken as string;
62+
const srcOrgInstUrl = sourceOrgObj.getConnection().instanceUrl as string;
63+
64+
const targetOrg = targetOrgObj.getOrgId();
65+
const tgtAccessToken = targetOrgObj.getConnection().accessToken as string;
66+
const tgtOrgInstUrl = targetOrgObj.getConnection().instanceUrl as string;
67+
68+
//Fetch Valid JWT with Data Seed Org Perm
69+
const { jwt: jwtValue} = await initiateJWTMint(srcOrgInstUrl,srcAccessToken,tgtOrgInstUrl,tgtAccessToken);
70+
this.log("\nValid JWT Token Fetched.");
71+
72+
const { request_id: jobId } = await initiateDataSeed(configFile, 'data-copy',jwtValue);
6173

6274
if (!jobId) throw new Error('Failed to receive job id');
6375

src/utils/api.ts

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { SfError, Logger } from '@salesforce/core';
1414
export type SeedResponse = {
1515
request_id: string;
1616
};
17+
export type ServletResponse = {
18+
jwt: string;
19+
};
1720

1821
export type PollSeedResponse = {
1922
execution_end_time: string;
@@ -26,7 +29,8 @@ export type PollSeedResponse = {
2629

2730
export type DataSeedingOperation = 'data-generation' | 'data-copy';
2831

29-
const baseUrl = process.env.SF_DATA_SEEDING_URL ?? 'https://data-seed-scratchpad5.sfdc-3vx9f4.svc.sfdcfc.net';
32+
// TODO Change to SFAP Endpoint
33+
const baseUrl = process.env.SF_DATA_SEEDING_URL ?? 'https://data-seed-gid.sfdc-yfeipo.svc.sfdcfc.net';
3034
const csrfUrl = `${baseUrl}/get-csrf-token`;
3135
const seedUrl = `${baseUrl}/data-seed`;
3236
const pollUrl = `${baseUrl}/status`;
@@ -44,23 +48,23 @@ export const getCsrfToken = (cookieJar: CookieJar): string => {
4448
return csrfToken;
4549
};
4650

47-
export const initiateDataSeed = async (config: string, operation: DataSeedingOperation): Promise<SeedResponse> => {
48-
const cookieJar = await getCookieJar();
49-
const csrf = getCsrfToken(cookieJar);
50-
51+
export const initiateDataSeed = async (config: string, operation: DataSeedingOperation, jwt: string): Promise<SeedResponse> => {
52+
//const cookieJar = await getCookieJar();
53+
//const csrf = getCsrfToken(cookieJar);
5154
const form = new FormData();
5255
form.append('config_file', fs.createReadStream(config));
56+
// TODO : Remove credential file once SFAP is active and dataseed endpoint accepts orgurl and token
5357
form.append('credentials_file', fs.createReadStream('ignore/credentials.txt'));
5458
form.append('operation', operation);
55-
5659
// TODO: Update to use .json() instead of JSON.parse once the Error response is changed to be JSON
5760
// Update the return type as well
5861
const response = await got.post(seedUrl, {
5962
throwHttpErrors: false,
60-
cookieJar,
63+
//cookieJar,
6164
headers: {
6265
...form.getHeaders(),
63-
'X-CSRFToken': csrf,
66+
// 'X-CSRFToken': csrf,
67+
'Authorization': 'Bearer '+jwt,
6468
},
6569
body: form,
6670
});
@@ -72,6 +76,33 @@ export const initiateDataSeed = async (config: string, operation: DataSeedingOpe
7276
return JSON.parse(response.body) as SeedResponse;
7377
};
7478

79+
export const initiateJWTMint = async (src_org_url: string, src_access_token: string, tgt_org_url: string, tgt_access_token: string ): Promise<ServletResponse> => {
80+
81+
const src_servlet_url = src_org_url+'/dataseed/auth'
82+
const response_src = await got.post(src_servlet_url, {
83+
throwHttpErrors: false,
84+
headers: {
85+
'Authorization': 'Bearer '+src_access_token,
86+
},
87+
});
88+
89+
if (response_src.statusCode !== 200) {
90+
const tgt_servlet_url = tgt_org_url+'/dataseed/auth'
91+
const response_tgt = await got.post(tgt_servlet_url, {
92+
throwHttpErrors: false,
93+
headers: {
94+
'Authorization': 'Bearer '+tgt_access_token,
95+
},
96+
});
97+
if (response_tgt.statusCode !== 200) {
98+
throw new SfError(`Org permission for data seed not found in source & target org.\nSource Response: Error Code : ${response_src.statusCode} - ${response_src.body}. \nTarget Response: Error Code : ${response_tgt.statusCode} - ${response_tgt.body}`);
99+
}
100+
return JSON.parse(response_tgt.body) as ServletResponse;
101+
}
102+
103+
return JSON.parse(response_src.body) as ServletResponse;
104+
};
105+
75106
export const pollSeedStatus = async (jobId: string): Promise<PollSeedResponse> => {
76107
const logger = await Logger.child('PollSeedStatus');
77108

0 commit comments

Comments
 (0)