@docupace/pipeline 1.0.23 → 1.0.24-alpha-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docupace/pipeline",
3
- "version": "1.0.23",
3
+ "version": "1.0.24-alpha-3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -17,7 +17,6 @@
17
17
  "dependencies": {
18
18
  "@changesets/cli": "^2.27.10",
19
19
  "@docupace/core-client": "^0.1.59",
20
- "auth0-deploy-cli": "^7.24.3",
21
20
  "axios": "^1.7.9",
22
21
  "commander": "^12.1.0",
23
22
  "dotenv": "^16.4.7",
package/src/auth0/cli.js CHANGED
@@ -18,17 +18,18 @@ dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
18
18
  const program = new Command();
19
19
 
20
20
  program
21
- .command('configureFromSite <fromSite> <toSite> <fromEnv> <toEnv> <deployUI> <deployGraphQLServer> <useNewDomain> <configureMFA>')
21
+ .command('configureFromSite <fromSite> <toSite> <fromEnv> <toEnv> <deployUI> <deployGraphQLServer> <useNewDomain>')
22
22
  .description('Configure the Auth0 tenants in env for the given site')
23
- .action(async (fromSite, toSite, fromEnv,toEnv, deployUI, deployGraphQLServer, useNewDomain, configureMFA) => {
24
- await configureFromSite(fromSite, toSite, fromEnv, toEnv, deployUI, deployGraphQLServer, useNewDomain, configureMFA);
23
+ .action(async (fromSite, toSite, fromEnv,toEnv, deployUI, deployGraphQLServer, useNewDomain) => {
24
+ await configureFromSite(fromSite, toSite, fromEnv, toEnv, deployUI, deployGraphQLServer, useNewDomain);
25
25
  });
26
26
 
27
27
  program
28
28
  .command('getVaultSecrets <vaultPath>')
29
29
  .description('Get Secrets for Vault PATH')
30
30
  .action(async (vaultPath) => {
31
- await getVaultSecrets(vaultPath);
31
+ const data = await getVaultSecrets(vaultPath);
32
+ console.log(JSON.stringify(data, 'null', 2));
32
33
  });
33
34
 
34
35
  program
@@ -2,7 +2,6 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import axios from 'axios';
4
4
  import crypto from 'crypto';
5
- import { deploy } from 'auth0-deploy-cli';
6
5
  import fl from 'fs/promises';
7
6
 
8
7
  import {
@@ -54,297 +53,6 @@ async function copyDirectory(source, destination) {
54
53
  }
55
54
  }
56
55
 
57
- async function addApplicationToApi ({application, auth0Domain, auth0AuthToken, coreApiIdentifier}){
58
- console.log("Adding application to API authorized applications...");
59
-
60
- try {
61
- const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
62
- headers: {authorization: `Bearer ${auth0AuthToken}`},
63
- });
64
-
65
- const appAuth0ClientIdData = auth0Response.data.find(client => client.name === `${application}`);
66
- const appAuth0ClientId = appAuth0ClientIdData.client_id;
67
-
68
- await axios.post(
69
- `https://${auth0Domain}/api/v2/client-grants`,
70
- {
71
- client_id: appAuth0ClientId,
72
- audience: `${coreApiIdentifier}`,
73
- scope: [],
74
- },
75
- {
76
- headers: {
77
- Authorization: `Bearer ${auth0AuthToken}`,
78
- "Content-Type": "application/json",
79
- },
80
- }
81
- );
82
- console.log(`Application (${appAuth0ClientId}) authorized for API: ${coreApiIdentifier}`);
83
- } catch (err) {
84
- console.error(`Failed to add application: ${application}: ${err.message}`);
85
- }
86
-
87
- }
88
-
89
- async function initializeAuth0Configuration({
90
- initConfiguration,
91
- auth0Domain,
92
- auth0AuthToken,
93
- coreApiIdentifier,
94
- }) {
95
- if (initConfiguration === "true") {
96
- try {
97
- // Create a new resource server in Auth0
98
- console.log("Creating resource server in Auth0...");
99
-
100
- const resourceServerResponse = await axios.post(
101
- `https://${auth0Domain}/api/v2/resource-servers`,
102
- {
103
- name: "docupace-core",
104
- identifier: `${coreApiIdentifier}`,
105
- token_lifetime: 86400,
106
- allow_offline_access: false,
107
- signing_alg: "RS256",
108
- skip_consent_for_verifiable_first_party_clients: true,
109
- scopes: [],
110
- },
111
- {
112
- headers: {
113
- Authorization: `Bearer ${auth0AuthToken}`,
114
- "Content-Type": "application/json",
115
- },
116
- }
117
- );
118
-
119
- const apiId = resourceServerResponse.data.id;
120
-
121
- // Update tenant settings with the default audience
122
- console.log("Updating tenant settings...");
123
- await axios.patch(
124
- `https://${auth0Domain}/api/v2/tenants/settings`,
125
- {
126
- default_audience: `${coreApiIdentifier}`,
127
- },
128
- {
129
- headers: {
130
- Authorization: `Bearer ${auth0AuthToken}`,
131
- "Content-Type": "application/json",
132
- },
133
- }
134
- );
135
- console.log("Tenant settings updated successfully.");
136
- } catch (error) {
137
- console.error("Error during Auth0 configuration:", error.response?.data || error.message);
138
- }
139
- }
140
- }
141
-
142
- async function importAuth0Templates(directoryPath, auth0Domain, auth0ClientID, auth0ClientSecret) {
143
- try {
144
- const config = {
145
- input_file: directoryPath,
146
- config: {
147
- AUTH0_DOMAIN: auth0Domain,
148
- AUTH0_CLIENT_ID: auth0ClientID,
149
- AUTH0_CLIENT_SECRET: auth0ClientSecret,
150
- },
151
- debug: true,
152
- };
153
-
154
- console.log('Starting Auth0 template import...');
155
- await deploy(config);
156
- console.log('Auth0 template import completed successfully!');
157
- } catch (error) {
158
- console.error('Error during Auth0 template import:', error.message);
159
- process.exit(1); // Exit with an error code
160
- }
161
- }
162
-
163
- async function updateJsonFile(filePath, updates) {
164
- const content = await fs.promises.readFile(filePath, 'utf8');
165
- const jsonContent = JSON.parse(content);
166
- const updatedContent = JSON.stringify({...jsonContent, ...updates}, null, 2);
167
- await fs.promises.writeFile(filePath, updatedContent);
168
- }
169
-
170
- async function replaceInFile(filePath, replacements) {
171
- let content = await fs.promises.readFile(filePath, 'utf8');
172
-
173
- for (const [search, replace] of replacements) {
174
- const escapedSearch = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); // Escape special chars
175
- content = content.replace(new RegExp(escapedSearch, 'g'), replace);
176
- }
177
- await fs.promises.writeFile(filePath, content, 'utf8');
178
- }
179
-
180
- async function templateAuth0(siteUrl, coreApiContext, env, filePaths, deployUI, deployGraphQLServer, commonSecrets, configureMFA) {
181
- try {
182
- let uiAllowedCallbacksUrls,
183
- uiAllowedLogoutUrls;
184
- let graphqlAllowedCallbacksUrls,
185
- graphqlAllowedLogoutUrls;
186
- let connectAllowedCallbacksUrls,
187
- connectlAllowedLogoutUrls;
188
-
189
- let connectClientMetadata,
190
- connectCallbacks,
191
- connectAddons;
192
- // Configure URLs based on environment
193
- if (env === 'prd') {
194
- uiAllowedCallbacksUrls = [`${siteUrl}/api/auth/callback`];
195
- uiAllowedLogoutUrls = [`${siteUrl}`];
196
-
197
- graphqlAllowedCallbacksUrls = [`${siteUrl}/api/graphql/callback`];
198
- graphqlAllowedLogoutUrls = [`${siteUrl}/api/graphql/`];
199
-
200
- connectAllowedCallbacksUrls = [`${siteUrl}/connect/samlCallback?client_name=auth0`];
201
- connectlAllowedLogoutUrls = [ `${siteUrl}/connect`];
202
- } else {
203
- uiAllowedCallbacksUrls = [
204
- `${siteUrl}/api/auth/callback`,
205
- `http://localhost:3000/api/auth/callback`,
206
- ];
207
- uiAllowedLogoutUrls = [
208
- `${siteUrl}`,
209
- `http://localhost:3000`,
210
- ];
211
- graphqlAllowedCallbacksUrls = [
212
- `${siteUrl}/api/graphql/callback`,
213
- `http://localhost:4000/api/graphql/callback`,
214
- ];
215
- graphqlAllowedLogoutUrls = [
216
- `http://localhost:4000/api/graphql/`,
217
- `${siteUrl}/api/graphql/`,
218
- ];
219
- connectAllowedCallbacksUrls = [
220
- `${siteUrl}/connect/samlCallback?client_name=auth0`,
221
- `http://localhost:9000/connect/samlCallback?client_name=auth0`,
222
- ];
223
- connectlAllowedLogoutUrls = [
224
- `${siteUrl}/connect`
225
- ];
226
-
227
- const siteUrlNoPrefix=siteUrl.replace(/^https?:\/\//, '');
228
- connectClientMetadata ={
229
- "docupaceContext" : "core",
230
- "docupaceHost" : `${siteUrlNoPrefix}`,
231
- "docupace_context" : "core",
232
- "docupace_host" : `${siteUrlNoPrefix} `
233
- };
234
-
235
- connectCallbacks = [
236
- `${siteUrl}/connect/samlCallback?client_name=auth0`
237
- ];
238
-
239
- connectAddons = {
240
- "samlp": {
241
- "audience": `${siteUrl}/connect`,
242
- "recipient": `${siteUrl}/connect/samlCallback?client_name=auth0`,
243
- "destination": `${siteUrl}/connect/samlCallback?client_name=auth0`,
244
- "nameIdentifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
245
- "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
246
- "nameIdentifierProbes": [
247
- "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/docupace-username"
248
- ],
249
- "mappings": {
250
- "proposalHandle": "ProposalHandle"
251
- }
252
- }
253
- };
254
-
255
- }
256
-
257
-
258
- const configureUI = deployUI === 'true';
259
- if (configureUI) {
260
- console.log('ui_allowed_callbacks_urls ->', uiAllowedCallbacksUrls);
261
- console.log('ui_allowed_logout_urls ->', uiAllowedLogoutUrls);
262
-
263
- await updateJsonFile(filePaths.uiJson, {
264
- callbacks: uiAllowedCallbacksUrls,
265
- allowed_logout_urls: uiAllowedLogoutUrls,
266
- });
267
-
268
-
269
- //TODO: move to separate function for connect
270
- console.log('connect_allowed_callbacks_urls ->', connectAllowedCallbacksUrls);
271
- console.log('connect_allowed_logout_urls ->', connectlAllowedLogoutUrls);
272
-
273
- // update allowed callback url
274
- await updateJsonFile(filePaths.connectJson, {
275
- callbacks: connectAllowedCallbacksUrls,
276
- allowed_logout_urls: connectlAllowedLogoutUrls,
277
- client_metadata: connectClientMetadata,
278
- addons: connectAddons
279
- });
280
-
281
-
282
-
283
- console.log('Updated URLs for main UI...');
284
- } else {
285
- await fs.promises.unlink(filePaths.uiJson);
286
- await updateJsonFile(filePaths.databaseJson, {
287
- enabled_clients: (content) => content.enabled_clients.filter((client) => client !== 'docupace-ui-main'),
288
- });
289
- console.log("Removed 'docupace-ui-main' from enabled_clients in database.json");
290
- }
291
-
292
- const configureGraphqlServer = deployGraphQLServer === 'true';
293
- if (configureGraphqlServer) {
294
- console.log('graphql_allowed_callbacks_urls ->', graphqlAllowedCallbacksUrls);
295
- console.log('graphql_allowed_logout_urls ->', graphqlAllowedLogoutUrls);
296
-
297
- await updateJsonFile(filePaths.graphqlJson, {
298
- callbacks: graphqlAllowedCallbacksUrls,
299
- allowed_logout_urls: graphqlAllowedLogoutUrls,
300
- });
301
- console.log('Updated URLs for GraphQL server...');
302
- } else {
303
- await fs.promises.unlink(filePaths.graphqlJson);
304
- await updateJsonFile(filePaths.databaseJson, {
305
- enabled_clients: (content) => content.enabled_clients.filter((client) => client !== 'docupace-graphql'),
306
- });
307
- console.log("Removed 'docupace-graphql' from enabled_clients in database.json");
308
- }
309
-
310
- // TWILIO configuration
311
- await replaceInFile(filePaths.twilioJson, [
312
- ['twilioauthtokenplaceholder', commonSecrets.TWILIO_AUTH_TOKEN],
313
- ['twiliosidplaceholder', commonSecrets.TWILIO_SID],
314
- ['twiliofromplaceholder', commonSecrets.TWILIO_FROM_NUMBER],
315
- ]);
316
-
317
- console.log('TWILIO configuration updated...');
318
-
319
- const tmpSiteUrl = siteUrl.replace(/^https?:\/\//, '');
320
- // Database configuration
321
- await replaceInFile(filePaths.databaseLoginJs, [
322
- ['${docupaceHost}', tmpSiteUrl],
323
- ['${docupaceContext}', coreApiContext],
324
- ]);
325
-
326
- console.log('MFA Template configuration started...');
327
-
328
- try {
329
- const sourceDir = configureMFA === 'DISABLED' ? 'auth0-site-setup/templateNoMFA/' : 'auth0-site-setup/templateMFA/';
330
- const destinationDir = 'auth0-site-setup/template/';
331
-
332
- console.log(`AUTH0 MFA is ${configureMFA === 'DISABLED' ? 'disabled' : 'enabled'}`);
333
- await copyDirectory(sourceDir, destinationDir);
334
-
335
- console.log('MFA configuration completed.');
336
- } catch (err) {
337
- console.error('Error configuring MFA:', err);
338
- throw err;
339
- }
340
-
341
- console.log('Template configuration completed.');
342
- } catch (err) {
343
- // console.error('Error configuring Auth0 templates:', err);
344
- throw err;
345
- }
346
- }
347
-
348
56
  export async function getAuth0AuthToken(auth0Domain, clientId, clientSecret) {
349
57
  try {
350
58
  const response = await axios.post(`https://${auth0Domain}/oauth/token`, {
@@ -604,8 +312,7 @@ ingress:
604
312
  }
605
313
  }
606
314
 
607
-
608
- export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployUI, deployGraphQLServer, useNewDomain, configureMFA) {
315
+ export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployUI, deployGraphQLServer, useNewDomain) {
609
316
  console.log(`Configuring Auth0 tenants and ArgoCD apps for site: ${toSite} in env: ${toEnv} from site: ${fromSite}`);
610
317
  // Common Secrets
611
318
  const commonSecretsPath = getVaultSecretsConfigs(toSite).commonSecretsPath;
@@ -633,17 +340,17 @@ export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployU
633
340
  let repoPathFromEnv ="";
634
341
  let repoPathToEnv = "";
635
342
  // Clone repositories
636
- if ( fromEnv == toEnv ) {
343
+ if ( fromEnv === toEnv ) {
637
344
  repoPathFromEnv = await cloneEnvRepository(fromEnv);
638
345
  repoPathToEnv = repoPathFromEnv;
639
- }else {
346
+ } else {
640
347
  repoPathFromEnv = await cloneEnvRepository(fromEnv);
641
348
  repoPathToEnv = await cloneEnvRepository(toEnv);
642
349
  }
643
350
 
644
351
  //TODO: clone fromEnv and toEnv. replace above with this
645
352
 
646
- const auth0RepoPath = await cloneRepository('auth0-site-setup');
353
+ // const auth0RepoPath = await cloneRepository('auth0-site-setup');
647
354
 
648
355
  // Read deploy configs
649
356
  const { deployConfig: deployUIConfig } = await readDeployConfig('ui', fromEnv, fromSite, 'values');
@@ -689,9 +396,6 @@ export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployU
689
396
  CONNECT_URL = `${oldUrl}_ui`;
690
397
  }
691
398
 
692
- await templateAuth0(SITE_HOST, CORE_API_CONTEXT, toEnv, filePaths, deployUI, deployGraphQLServer, commonSecrets, configureMFA);
693
- await importAuth0Templates('./auth0-site-setup/template', auth0Domain, auth0ClientId, auth0ClientSecret);
694
-
695
399
  if (deployUI === 'true') {
696
400
  await configureUI(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, toEnv, useNewDomain, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, uiSecretsPath, uiImageTag, repoPathToEnv);
697
401
  }
@@ -699,17 +403,4 @@ export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployU
699
403
  await configureGraphQLServer(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, toEnv, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, graphqlSecretsPath, graphqlImageTag, graphqlStandardConfigRemoteBranch, repoPathToEnv, commonSecrets);
700
404
  await pushDeployConfig(repoPathToEnv, `Config update for ${toSite} from ${fromSite} with UI: ${uiImageTag} and GraphQL: ${graphqlImageTag}`);
701
405
 
702
- await initializeAuth0Configuration({
703
- initConfiguration: "true",
704
- auth0Domain: auth0Domain,
705
- auth0AuthToken: auth0Token,
706
- coreApiIdentifier: commonSecrets.CORE_API_IDENTIFIER,
707
- });
708
-
709
- await addApplicationToApi({
710
- application: 'docupace-graphql-client-credentials',
711
- auth0Domain: auth0Domain,
712
- auth0AuthToken: auth0Token,
713
- coreApiIdentifier: commonSecrets.CORE_API_IDENTIFIER
714
- })
715
406
  }
@@ -36,7 +36,7 @@ const connectUIEnvMap= {
36
36
  function log(msg) {
37
37
  console.log(`[*] ${msg}`);
38
38
  }
39
-
39
+
40
40
  /* --------------------------------
41
41
  * 1. GIT CHECKOUT
42
42
  * -------------------------------- */
@@ -48,21 +48,16 @@ function log(msg) {
48
48
  await fs.remove(destDir);
49
49
  log(`Cloning ${destDir} repository...`);
50
50
  }
51
-
51
+
52
52
  const username = process.env.BITBUCKET_USERNAME;
53
53
  const password = process.env.BITBUCKET_APP_PASSWORD;
54
-
54
+
55
55
  // Construct clone command
56
56
  const cloneUrl = `https://${username}:${password}@bitbucket.org/dp-cloud/${repository}.git`;
57
-
57
+
58
58
  log(`Perform cloning`);
59
59
  await $`git clone --branch=${branch} --depth 1 ${cloneUrl} ${destDir}`;
60
60
  }
61
-
62
-
63
-
64
-
65
-
66
61
 
67
62
  export async function connectClone() {
68
63
  const connectFromEnv = connectUIEnvMap[process.env.BUILD_ENVIRONMENT];
@@ -78,8 +73,8 @@ export async function connectClone() {
78
73
  process.exit(1);
79
74
  }
80
75
  const siteCommonVaultPath = `secret/data/${site}/common/config`;
81
-
82
-
76
+
77
+
83
78
  // 2) getVaultSecrets
84
79
  const secretsJson = await getVaultSecrets(siteCommonVaultPath);
85
80
  if (!secretsJson.AUTH0_CLIENT_ID) {
@@ -87,12 +82,12 @@ export async function connectClone() {
87
82
  process.exit(1);
88
83
  }
89
84
  const siteCommonSecrets = secretsJson;
90
-
85
+
91
86
  // 3) Export secrets as environment variables
92
87
  process.env.AUTH0_CLIENT_ID = siteCommonSecrets.AUTH0_CLIENT_ID;
93
88
  process.env.AUTH0_CLIENT_SECRET = siteCommonSecrets.AUTH0_CLIENT_SECRET;
94
-
95
-
89
+
90
+
96
91
  process.env.AUTH0_REGION_DOMAIN="us.auth0.com";
97
92
 
98
93
  log(`BUILD_ENVIRONMENT: ${connectToEnv}`);
@@ -100,16 +95,16 @@ export async function connectClone() {
100
95
  log(`AUTH0_SUBDOMAIN: ${process.env.AUTH0_SUBDOMAIN}`);
101
96
  log(`AUTH0_REGION_DOMAIN: ${process.env.AUTH0_REGION_DOMAIN}`);
102
97
  log(`AUTH0_CLIENT_ID: ${process.env.AUTH0_CLIENT_ID}`);
103
-
98
+
104
99
  process.env.AUTH0_DOMAIN = `docupace-${process.env.BUILD_ENVIRONMENT}-${process.env.BUILD_SITE}.${process.env.AUTH0_REGION_DOMAIN}`;
105
-
100
+
106
101
 
107
102
  const projectRoot = process.cwd();
108
103
  // 4) Clone 'connect-deploy' into CONNECT_DIR
109
104
 
110
-
105
+
111
106
  await gitCheckout('connect-deploy', process.env.CONNECT_DIR);
112
-
107
+
113
108
  await gitCheckout(`${connectToEnv}-site-settings`, `${process.env.CONNECT_DIR}/${connectToEnv}-site-settings`);
114
109
 
115
110
  // 5) Create site clone (emulating the dock.sh call)
@@ -121,8 +116,8 @@ export async function connectClone() {
121
116
  log('Clone template directory not found:');
122
117
  process.exit(1);
123
118
  }
124
-
125
-
119
+
120
+
126
121
  if (!(await fs.pathExists(cloneTo))) {
127
122
  log('New site does not exist. Performing cloning...');
128
123
 
@@ -144,13 +139,13 @@ export async function connectClone() {
144
139
  console.error('stderr:', error._stderr); // Standard error
145
140
  }
146
141
  })();
147
-
148
-
142
+
143
+
149
144
  } else {
150
145
  log('Site already exists. Continuing Auth0 setup...');
151
146
  }
152
-
153
-
147
+
148
+
154
149
  await (async () => {
155
150
  try {
156
151
  // Execute the shell command
@@ -173,7 +168,7 @@ export async function connectClone() {
173
168
  await $`ls -all ${path.join(cloneTo, 'conf')}`;
174
169
  await $`ls -all ${path.join(cloneTo, 'conf/saml')}`;
175
170
  await $`cat ${path.join(cloneTo, 'conf/saml/auth0.xml')}`;
176
-
171
+
177
172
  // 8) Git add, commit, push
178
173
  await $`cd ${cloneTo} && git checkout master && git pull --ff-only`;
179
174
  await $`cd ${cloneTo} && git remote -v`;
@@ -181,11 +176,11 @@ export async function connectClone() {
181
176
  await $`cd ${cloneTo} && git status`;
182
177
  await $`cd ${cloneTo} && git add . ../sites.sh`;
183
178
  await $`cd ${cloneTo} && git status`;
184
-
179
+
185
180
  const numChanges = (
186
181
  await $`cd ${cloneTo} && git diff-index HEAD`
187
182
  ).stdout.split('\n').filter(Boolean).length;
188
-
183
+
189
184
  if (numChanges > 0) {
190
185
  const jiraTicket = process.env.JIRA_TICKET || 'NO_JIRA';
191
186
  const message = `${jiraTicket} usdoc-s-builui job download_auth0_metadata for ${connectToEnv}/${process.env.BUILD_SITE}`;
@@ -196,4 +191,4 @@ export async function connectClone() {
196
191
  log('No changes have been made. The site likely already has the correct configuration.');
197
192
  }
198
193
  }
199
-
194
+