@docupace/pipeline 1.0.26-alpha-4 → 1.0.26
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/.prettierrc.cjs +12 -12
- package/bin/next-changeset-validate.sh +8 -8
- package/next/changeset.sh +75 -75
- package/next/copy.sh +34 -34
- package/next/deploy.sh +40 -40
- package/next/execute.sh +117 -117
- package/next/sonar.sh +23 -23
- package/package.json +2 -1
- package/src/auth0/alias.js +75 -72
- package/src/auth0/cli.js +41 -56
- package/src/auth0/configure.js +451 -227
- package/src/auth0/vault.js +107 -107
- package/src/changeset/cli.js +281 -281
- package/src/changeset/validate.js +47 -47
- package/src/jenkins/setParams.groovy +59 -59
- package/src/next/alias.js +53 -53
- package/src/next/apache.js +40 -40
- package/src/next/cli.js +185 -173
- package/src/next/connect.js +157 -162
- package/src/next/copy.js +52 -30
- package/src/next/deploy.js +218 -43
- package/src/next/jenkins.js +123 -122
- package/src/next/pipline.js +114 -115
- package/src/next/publish.js +48 -48
- package/src/next/pull.js +7 -7
- package/src/next/sonar.js +23 -23
- package/src/next/vault.js +43 -43
- package/terraform/apply.sh +26 -26
- package/terraform/init.sh +48 -60
- package/terraform/plan.sh +54 -61
- package/terraform/validate.sh +17 -17
package/src/auth0/configure.js
CHANGED
|
@@ -2,15 +2,27 @@ 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
|
+
import fl from 'fs/promises';
|
|
5
7
|
|
|
6
8
|
import {
|
|
7
9
|
cloneEnvRepository,
|
|
10
|
+
cloneRepository,
|
|
8
11
|
readDeployConfig,
|
|
9
|
-
pushDeployConfig
|
|
12
|
+
pushDeployConfig
|
|
10
13
|
} from '../next/deploy.js';
|
|
11
14
|
|
|
12
|
-
import {
|
|
13
|
-
|
|
15
|
+
import {
|
|
16
|
+
getVaultSecrets,
|
|
17
|
+
updateVaultSecrets
|
|
18
|
+
} from './vault.js';
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
getVaultSecretsConfigs,
|
|
22
|
+
environmentConfig
|
|
23
|
+
} from '../next/config.js';
|
|
24
|
+
import { connect } from 'http2';
|
|
25
|
+
import { promise } from 'zod';
|
|
14
26
|
|
|
15
27
|
async function ensureDirectoryExists(dirPath) {
|
|
16
28
|
try {
|
|
@@ -21,76 +33,359 @@ async function ensureDirectoryExists(dirPath) {
|
|
|
21
33
|
}
|
|
22
34
|
}
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
async function copyDirectory(source, destination) {
|
|
37
|
+
try {
|
|
38
|
+
await fl.mkdir(destination, { recursive: true });
|
|
39
|
+
const items = await fl.readdir(source, { withFileTypes: true });
|
|
40
|
+
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
const sourcePath = path.join(source, item.name);
|
|
43
|
+
const destinationPath = path.join(destination, item.name);
|
|
44
|
+
|
|
45
|
+
if (item.isDirectory()) {
|
|
46
|
+
await copyDirectory(sourcePath, destinationPath);
|
|
47
|
+
} else {
|
|
48
|
+
await fl.copyFile(sourcePath, destinationPath);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.error(`Error copying directory: ${err.message}`);
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function addApplicationToApi ({application, auth0Domain, auth0AuthToken, coreApiIdentifier}){
|
|
58
|
+
console.log("Adding application to API authorized applications...");
|
|
59
|
+
|
|
25
60
|
try {
|
|
26
|
-
const
|
|
27
|
-
`
|
|
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`,
|
|
28
70
|
{
|
|
29
|
-
client_id:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
grant_type: 'client_credentials',
|
|
71
|
+
client_id: appAuth0ClientId,
|
|
72
|
+
audience: `${coreApiIdentifier}`,
|
|
73
|
+
scope: [],
|
|
33
74
|
},
|
|
34
75
|
{
|
|
35
76
|
headers: {
|
|
36
|
-
|
|
77
|
+
Authorization: `Bearer ${auth0AuthToken}`,
|
|
78
|
+
"Content-Type": "application/json",
|
|
37
79
|
},
|
|
38
|
-
}
|
|
80
|
+
}
|
|
39
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
|
+
export async function getAuth0AuthToken(auth0Domain, clientId, clientSecret) {
|
|
349
|
+
try {
|
|
350
|
+
const response = await axios.post(`https://${auth0Domain}/oauth/token`, {
|
|
351
|
+
client_id: clientId,
|
|
352
|
+
client_secret: clientSecret,
|
|
353
|
+
audience: `https://${auth0Domain}/api/v2/`,
|
|
354
|
+
grant_type: 'client_credentials',
|
|
355
|
+
}, {
|
|
356
|
+
headers: {
|
|
357
|
+
'Content-Type': 'application/json',
|
|
358
|
+
},
|
|
359
|
+
});
|
|
40
360
|
|
|
41
361
|
const authToken = response.data.access_token;
|
|
42
362
|
// console.log("Auth0 Auth Token:", authToken);
|
|
43
363
|
return authToken;
|
|
44
364
|
} catch (error) {
|
|
45
|
-
console.error(
|
|
46
|
-
'Error fetching Auth0 token:',
|
|
47
|
-
error.response ? error.response.data : error.message,
|
|
48
|
-
);
|
|
365
|
+
console.error("Error fetching Auth0 token:", error.response ? error.response.data : error.message);
|
|
49
366
|
}
|
|
50
367
|
}
|
|
51
368
|
|
|
52
|
-
async function configureUI(
|
|
53
|
-
siteHost
|
|
54
|
-
coreURL,
|
|
55
|
-
docupaceHost,
|
|
56
|
-
site,
|
|
57
|
-
env,
|
|
58
|
-
auth0Domain,
|
|
59
|
-
auth0ClientId,
|
|
60
|
-
auth0ClientSecret,
|
|
61
|
-
auth0Token,
|
|
62
|
-
vaultSiteSecretsPath,
|
|
63
|
-
imageTag,
|
|
64
|
-
repoPath,
|
|
65
|
-
) {
|
|
66
|
-
console.log(
|
|
67
|
-
`Configuring UI for site: ${site} Host: ${siteHost} in env: ${env}`,
|
|
68
|
-
);
|
|
369
|
+
async function configureUI(siteHost, coreURL, docupaceHost, site, env, useNewDomain, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, vaultSiteSecretsPath, imageTag, repoPath) {
|
|
370
|
+
console.log(`Configuring UI for site: ${site} Host: ${siteHost} in env: ${env}`);
|
|
69
371
|
siteHost = siteHost.replace('https://', '');
|
|
70
372
|
coreURL = coreURL.replace('https://', '');
|
|
71
373
|
|
|
374
|
+
|
|
72
375
|
try {
|
|
73
|
-
const auth0Response = await axios.get(
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
headers: { authorization: `Bearer ${auth0Token}` },
|
|
77
|
-
},
|
|
78
|
-
);
|
|
376
|
+
const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
|
|
377
|
+
headers: {authorization: `Bearer ${auth0Token}`},
|
|
378
|
+
});
|
|
79
379
|
|
|
80
|
-
const uiClient = auth0Response.data.find(
|
|
81
|
-
(client) => client.name === 'docupace-ui-main',
|
|
82
|
-
);
|
|
380
|
+
const uiClient = auth0Response.data.find(client => client.name === "docupace-ui-main");
|
|
83
381
|
const uiAuth0ClientId = uiClient.client_id;
|
|
84
382
|
const uiAuth0ClientSecret = uiClient.client_secret;
|
|
85
383
|
|
|
86
384
|
// Generate Auth0 Secret
|
|
87
|
-
const uiAuth0Secret = crypto
|
|
88
|
-
.randomBytes(48)
|
|
89
|
-
.toString('base64')
|
|
90
|
-
.replace(/[^a-zA-Z0-9]/g, '');
|
|
385
|
+
const uiAuth0Secret = crypto.randomBytes(48).toString('base64').replace(/[^a-zA-Z0-9]/g, '');
|
|
91
386
|
|
|
92
387
|
// Prepare data payload
|
|
93
|
-
console.log(
|
|
388
|
+
console.log("Preparing Vault UI data payload...");
|
|
94
389
|
const uiSecretData = JSON.stringify({
|
|
95
390
|
data: {
|
|
96
391
|
AUTH0_CLIENT_ID: uiAuth0ClientId,
|
|
@@ -143,7 +438,7 @@ ingress:
|
|
|
143
438
|
- ${siteHost}
|
|
144
439
|
secretName: dp-next-ui-cert
|
|
145
440
|
externalConnectIngress:
|
|
146
|
-
enabled:
|
|
441
|
+
enabled: ${useNewDomain}
|
|
147
442
|
className: nginx
|
|
148
443
|
annotations:
|
|
149
444
|
cert-manager.io/cluster-issuer: letsencrypt
|
|
@@ -172,91 +467,57 @@ externalConnectIngress:
|
|
|
172
467
|
- ${siteHost}
|
|
173
468
|
secretName: dp-next-ui-cert
|
|
174
469
|
externalConnectService:
|
|
175
|
-
enabled:
|
|
470
|
+
enabled: ${useNewDomain}
|
|
176
471
|
name: external-connect
|
|
177
472
|
domain: ${docupaceHost}
|
|
178
473
|
`.trim();
|
|
179
474
|
|
|
180
475
|
// Write configuration files
|
|
181
|
-
console.log(
|
|
476
|
+
console.log("Writing configuration files...");
|
|
182
477
|
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
183
478
|
|
|
184
|
-
await fs.writeFile(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
console.log('File written successfully.');
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
);
|
|
479
|
+
await fs.writeFile(`${repoPath}/dp/${site}/ui.app.yaml`, uiAppYaml, (err) => {
|
|
480
|
+
if (err) {
|
|
481
|
+
console.error("Failed to write the file:", err);
|
|
482
|
+
} else {
|
|
483
|
+
console.log("File written successfully.");
|
|
484
|
+
}
|
|
485
|
+
});
|
|
195
486
|
|
|
196
|
-
await fs.writeFile(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
);
|
|
207
|
-
console.log('Done!');
|
|
487
|
+
await fs.writeFile(`${repoPath}/dp/${site}/ui.values.yaml`, uiValuesYaml, (err) => {
|
|
488
|
+
if (err) {
|
|
489
|
+
console.error("Failed to write the file:", err);
|
|
490
|
+
} else {
|
|
491
|
+
console.log("File written successfully.");
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
console.log("Done!");
|
|
208
495
|
} catch (error) {
|
|
209
|
-
console.error(
|
|
496
|
+
console.error("Error configuring UI:", error);
|
|
210
497
|
}
|
|
211
498
|
}
|
|
212
499
|
|
|
213
|
-
async function configureGraphQLServer(
|
|
214
|
-
siteHost,
|
|
215
|
-
coreURL,
|
|
216
|
-
docupaceHost,
|
|
217
|
-
site,
|
|
218
|
-
env,
|
|
219
|
-
auth0Domain,
|
|
220
|
-
auth0ClientId,
|
|
221
|
-
auth0ClientSecret,
|
|
222
|
-
auth0Token,
|
|
223
|
-
vaultSiteSecretsPath,
|
|
224
|
-
imageTag,
|
|
225
|
-
standardConfigRemoteBranch,
|
|
226
|
-
repoPath,
|
|
227
|
-
commonSecrets,
|
|
228
|
-
) {
|
|
500
|
+
async function configureGraphQLServer(siteHost, coreURL, docupaceHost, site, env, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, vaultSiteSecretsPath, imageTag, standardConfigRemoteBranch, repoPath, commonSecrets) {
|
|
229
501
|
siteHost = siteHost.replace('https://', '');
|
|
230
502
|
coreURL = coreURL.replace('https://', '');
|
|
231
|
-
console.log(
|
|
232
|
-
`Configuring GraphQL Server for site: ${site} Host: ${siteHost} in env: ${env}`,
|
|
233
|
-
);
|
|
503
|
+
console.log(`Configuring GraphQL Server for site: ${site} Host: ${siteHost} in env: ${env}`);
|
|
234
504
|
|
|
235
505
|
try {
|
|
236
|
-
const auth0Response = await axios.get(
|
|
237
|
-
`
|
|
238
|
-
|
|
239
|
-
headers: { authorization: `Bearer ${auth0Token}` },
|
|
240
|
-
},
|
|
241
|
-
);
|
|
506
|
+
const auth0Response = await axios.get(`https://${auth0Domain}/api/v2/clients`, {
|
|
507
|
+
headers: {authorization: `Bearer ${auth0Token}`},
|
|
508
|
+
});
|
|
242
509
|
|
|
243
|
-
const graphQLServerClient = auth0Response.data.find(
|
|
244
|
-
|
|
245
|
-
);
|
|
246
|
-
const graphQLServerClientCredentials = auth0Response.data.find(
|
|
247
|
-
(client) => client.name === 'docupace-graphql-client-credentials',
|
|
248
|
-
);
|
|
510
|
+
const graphQLServerClient = auth0Response.data.find(client => client.name === "docupace-graphql");
|
|
511
|
+
const graphQLServerClientCredentials = auth0Response.data.find(client => client.name === "docupace-graphql-client-credentials");
|
|
249
512
|
|
|
250
513
|
const graphQLServerAuth0ClientId = graphQLServerClient.client_id;
|
|
251
514
|
const graphQLServerAuth0ClientSecret = graphQLServerClient.client_secret;
|
|
252
515
|
|
|
253
|
-
const graphQLServerCCAuth0ClientId =
|
|
254
|
-
|
|
255
|
-
const graphQLServerCCAuth0ClientSecret =
|
|
256
|
-
graphQLServerClientCredentials.client_secret;
|
|
516
|
+
const graphQLServerCCAuth0ClientId = graphQLServerClientCredentials.client_id;
|
|
517
|
+
const graphQLServerCCAuth0ClientSecret = graphQLServerClientCredentials.client_secret;
|
|
257
518
|
|
|
258
519
|
// Prepare data payload
|
|
259
|
-
console.log(
|
|
520
|
+
console.log("Preparing Vault GraphQL Server data payload...");
|
|
260
521
|
const graphQLServerSecretData = JSON.stringify({
|
|
261
522
|
data: {
|
|
262
523
|
AUTH0_CLIENT_ID: graphQLServerAuth0ClientId,
|
|
@@ -319,128 +580,105 @@ ingress:
|
|
|
319
580
|
`.trim();
|
|
320
581
|
|
|
321
582
|
// Write configuration files
|
|
322
|
-
console.log(
|
|
583
|
+
console.log("Writing ArgoCD GraphQL Server configuration files...");
|
|
323
584
|
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
324
585
|
|
|
325
|
-
await fs.writeFile(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
console.log('File written successfully.');
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
);
|
|
586
|
+
await fs.writeFile(`${repoPath}/dp/${site}/graphql-server.app.yaml`, graphQLServerAppYaml, (err) => {
|
|
587
|
+
if (err) {
|
|
588
|
+
console.error("Failed to write the file:", err);
|
|
589
|
+
} else {
|
|
590
|
+
console.log("File written successfully.");
|
|
591
|
+
}
|
|
592
|
+
});
|
|
336
593
|
|
|
337
|
-
await fs.writeFile(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
},
|
|
347
|
-
);
|
|
348
|
-
console.log('Done!');
|
|
594
|
+
await fs.writeFile(`${repoPath}/dp/${site}/graphql-server.values.yaml`, graphQLServerValuesYaml, (err) => {
|
|
595
|
+
if (err) {
|
|
596
|
+
console.error("Failed to write the file:", err);
|
|
597
|
+
} else {
|
|
598
|
+
console.log("File written successfully.");
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
console.log("Done!");
|
|
349
602
|
} catch (error) {
|
|
350
|
-
console.error(
|
|
603
|
+
console.error("Error configuring GraphQL Server:", error);
|
|
351
604
|
}
|
|
352
605
|
}
|
|
353
606
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
toSite
|
|
357
|
-
fromEnv,
|
|
358
|
-
toEnv,
|
|
359
|
-
deployUI,
|
|
360
|
-
deployGraphQLServer,
|
|
361
|
-
useNewDomain,
|
|
362
|
-
) {
|
|
363
|
-
console.log(
|
|
364
|
-
`Configuring Auth0 tenants and ArgoCD apps for site: ${toSite} in env: ${toEnv} from site: ${fromSite}`,
|
|
365
|
-
);
|
|
607
|
+
|
|
608
|
+
export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployUI, deployGraphQLServer, useNewDomain, configureMFA) {
|
|
609
|
+
console.log(`Configuring Auth0 tenants and ArgoCD apps for site: ${toSite} in env: ${toEnv} from site: ${fromSite}`);
|
|
366
610
|
// Common Secrets
|
|
367
611
|
const commonSecretsPath = getVaultSecretsConfigs(toSite).commonSecretsPath;
|
|
368
|
-
console.log(`commonSecretsPath => ${commonSecretsPath}`)
|
|
612
|
+
console.log(`commonSecretsPath => ${commonSecretsPath}`)
|
|
369
613
|
const commonSecrets = await getVaultSecrets(commonSecretsPath);
|
|
370
614
|
|
|
371
615
|
// Site Common Secrets
|
|
372
|
-
const siteCommonSecretsPath =
|
|
373
|
-
|
|
374
|
-
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`);
|
|
616
|
+
const siteCommonSecretsPath = getVaultSecretsConfigs(toSite).siteCommonSecretsPath;
|
|
617
|
+
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`)
|
|
375
618
|
const siteCommonSecrets = await getVaultSecrets(siteCommonSecretsPath);
|
|
376
619
|
|
|
377
|
-
const auth0Domain = `docupace-${toEnv}-${toSite}.us.auth0.com
|
|
620
|
+
const auth0Domain = `docupace-${toEnv}-${toSite}.us.auth0.com`
|
|
378
621
|
const auth0ClientId = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
379
622
|
const auth0ClientSecret = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
380
|
-
const auth0Token = await getAuth0AuthToken(
|
|
381
|
-
auth0Domain,
|
|
382
|
-
auth0ClientId,
|
|
383
|
-
auth0ClientSecret,
|
|
384
|
-
);
|
|
623
|
+
const auth0Token = await getAuth0AuthToken(auth0Domain, auth0ClientId, auth0ClientSecret);
|
|
385
624
|
|
|
386
625
|
// UI app
|
|
387
626
|
const uiSecretsPath = getVaultSecretsConfigs(toSite).uiSecretsPath;
|
|
388
|
-
console.log(`uiSecretsPath => ${uiSecretsPath}`)
|
|
627
|
+
console.log(`uiSecretsPath => ${uiSecretsPath}`)
|
|
389
628
|
|
|
390
629
|
// GraphQL-Server app
|
|
391
|
-
const graphqlSecretsPath =
|
|
392
|
-
getVaultSecretsConfigs(toSite).graphqlServerSecretsPath;
|
|
630
|
+
const graphqlSecretsPath = getVaultSecretsConfigs(toSite).graphqlServerSecretsPath;
|
|
393
631
|
console.log(`graphqlSecretsPath => ${graphqlSecretsPath}`);
|
|
394
632
|
|
|
395
|
-
let repoPathFromEnv =
|
|
396
|
-
let repoPathToEnv =
|
|
633
|
+
let repoPathFromEnv ="";
|
|
634
|
+
let repoPathToEnv = "";
|
|
397
635
|
// Clone repositories
|
|
398
|
-
if (fromEnv
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
|
|
636
|
+
if ( fromEnv == toEnv ) {
|
|
637
|
+
repoPathFromEnv = await cloneEnvRepository(fromEnv);
|
|
638
|
+
repoPathToEnv = repoPathFromEnv;
|
|
639
|
+
}else {
|
|
640
|
+
repoPathFromEnv = await cloneEnvRepository(fromEnv);
|
|
641
|
+
repoPathToEnv = await cloneEnvRepository(toEnv);
|
|
404
642
|
}
|
|
405
643
|
|
|
406
644
|
//TODO: clone fromEnv and toEnv. replace above with this
|
|
407
645
|
|
|
408
|
-
|
|
646
|
+
const auth0RepoPath = await cloneRepository('auth0-site-setup');
|
|
409
647
|
|
|
410
648
|
// Read deploy configs
|
|
411
|
-
const { deployConfig: deployUIConfig } = await readDeployConfig(
|
|
412
|
-
'ui',
|
|
413
|
-
fromEnv,
|
|
414
|
-
fromSite,
|
|
415
|
-
'values',
|
|
416
|
-
);
|
|
649
|
+
const { deployConfig: deployUIConfig } = await readDeployConfig('ui', fromEnv, fromSite, 'values');
|
|
417
650
|
const uiImageTag = deployUIConfig.image.tag;
|
|
418
651
|
|
|
419
|
-
const { deployConfig: deployGraphQLServerConfig } = await readDeployConfig(
|
|
420
|
-
'graphql-server',
|
|
421
|
-
fromEnv,
|
|
422
|
-
fromSite,
|
|
423
|
-
'values',
|
|
424
|
-
);
|
|
652
|
+
const { deployConfig: deployGraphQLServerConfig } = await readDeployConfig('graphql-server', fromEnv, fromSite, 'values');
|
|
425
653
|
const graphqlImageTag = deployGraphQLServerConfig.image.tag;
|
|
426
|
-
const graphqlStandardConfigRemoteBranch =
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
654
|
+
const graphqlStandardConfigRemoteBranch = deployGraphQLServerConfig.graphqlServer.standardConfigRemoteBranch;
|
|
655
|
+
|
|
656
|
+
// File paths
|
|
657
|
+
const filePaths = {
|
|
658
|
+
databaseLoginJs: './auth0-site-setup/template/database-connections/docupace/login.js',
|
|
659
|
+
loginHtml: './auth0-site-setup/template/pages/login.html',
|
|
660
|
+
graphqlJson: './auth0-site-setup/template/clients/docupace-graphql.json',
|
|
661
|
+
uiJson: './auth0-site-setup/template/clients/docupace-ui-main.json',
|
|
662
|
+
connectJson: './auth0-site-setup/template/clients/docupace-connect.json',
|
|
663
|
+
databaseJson: './auth0-site-setup/template/database-connections/docupace/database.json',
|
|
664
|
+
twilioJson: './auth0-site-setup/template/guardian/providers/sms-twilio.json',
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
console.log(`Copying Latest UI Image Tag: ${deployUIConfig.image.tag} from site: ${fromSite} to site: ${toSite}`);
|
|
668
|
+
console.log(`Copying Latest GraphQL Server Image Tag: ${deployGraphQLServerConfig.image.tag} from site: ${fromSite} to site: ${toSite}`);
|
|
435
669
|
|
|
436
670
|
const envConfig = environmentConfig[toEnv];
|
|
437
671
|
|
|
438
|
-
let CORE_URL,
|
|
672
|
+
let CORE_URL,
|
|
673
|
+
SITE_HOST,
|
|
674
|
+
CORE_API_CONTEXT,
|
|
675
|
+
CONNECT_URL,
|
|
676
|
+
DOCUPACE_HOST;
|
|
439
677
|
if (useNewDomain) {
|
|
440
678
|
const newUrl = envConfig.newUrl(toSite);
|
|
441
679
|
CORE_URL = `${newUrl}/core`;
|
|
442
680
|
SITE_HOST = newUrl;
|
|
443
|
-
CORE_API_CONTEXT =
|
|
681
|
+
CORE_API_CONTEXT = "core";
|
|
444
682
|
CONNECT_URL = `${newUrl}/connect`;
|
|
445
683
|
DOCUPACE_HOST = envConfig.docupaceHost();
|
|
446
684
|
} else {
|
|
@@ -451,41 +689,27 @@ export async function configureFromSite(
|
|
|
451
689
|
CONNECT_URL = `${oldUrl}_ui`;
|
|
452
690
|
}
|
|
453
691
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
toSite,
|
|
460
|
-
toEnv,
|
|
461
|
-
auth0Domain,
|
|
462
|
-
auth0ClientId,
|
|
463
|
-
auth0ClientSecret,
|
|
464
|
-
auth0Token,
|
|
465
|
-
uiSecretsPath,
|
|
466
|
-
uiImageTag,
|
|
467
|
-
repoPathToEnv,
|
|
468
|
-
);
|
|
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
|
+
if (deployUI === 'true') {
|
|
696
|
+
await configureUI(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, toEnv, useNewDomain, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, uiSecretsPath, uiImageTag, repoPathToEnv);
|
|
469
697
|
}
|
|
470
698
|
|
|
471
|
-
await configureGraphQLServer(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
commonSecrets
|
|
486
|
-
)
|
|
487
|
-
await pushDeployConfig(
|
|
488
|
-
repoPathToEnv,
|
|
489
|
-
`Config update for ${toSite} from ${fromSite} with UI: ${uiImageTag} and GraphQL: ${graphqlImageTag}`,
|
|
490
|
-
);
|
|
699
|
+
await configureGraphQLServer(SITE_HOST, CORE_URL, DOCUPACE_HOST, toSite, toEnv, auth0Domain, auth0ClientId, auth0ClientSecret, auth0Token, graphqlSecretsPath, graphqlImageTag, graphqlStandardConfigRemoteBranch, repoPathToEnv, commonSecrets);
|
|
700
|
+
await pushDeployConfig(repoPathToEnv, `Config update for ${toSite} from ${fromSite} with UI: ${uiImageTag} and GraphQL: ${graphqlImageTag}`);
|
|
701
|
+
|
|
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
|
+
})
|
|
491
715
|
}
|