@docupace/pipeline 1.0.33-matttest.3 → 1.0.34
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 +3 -2
- package/src/auth0/alias.js +36 -39
- package/src/auth0/cli.js +48 -15
- package/src/auth0/configure.js +316 -450
- package/src/auth0/export.js +43 -0
- package/src/auth0/metadata.js +132 -0
- package/src/auth0/vault.js +3 -3
- package/src/next/cli.js +4 -29
- package/src/next/config.js +9 -0
- package/src/next/deploy.js +8 -16
- package/terraform/init.sh +21 -9
- package/terraform/plan.sh +12 -5
package/src/auth0/configure.js
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
1
|
+
import fs from 'fs-extra';
|
|
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';
|
|
7
5
|
|
|
8
6
|
import {
|
|
9
7
|
cloneEnvRepository,
|
|
10
|
-
cloneRepository,
|
|
11
8
|
readDeployConfig,
|
|
12
|
-
pushDeployConfig
|
|
9
|
+
pushDeployConfig,
|
|
10
|
+
cloneRepository,
|
|
13
11
|
} from '../next/deploy.js';
|
|
14
12
|
|
|
15
|
-
import {
|
|
16
|
-
getVaultSecrets,
|
|
17
|
-
updateVaultSecrets
|
|
18
|
-
} from './vault.js';
|
|
19
|
-
|
|
13
|
+
import { getVaultSecrets, updateVaultSecrets } from './vault.js';
|
|
20
14
|
import {
|
|
21
15
|
getVaultSecretsConfigs,
|
|
22
|
-
environmentConfig
|
|
16
|
+
environmentConfig,
|
|
17
|
+
coreSiteEnvMap,
|
|
23
18
|
} from '../next/config.js';
|
|
24
|
-
import { connect } from 'http2';
|
|
25
|
-
import { promise } from 'zod';
|
|
26
19
|
|
|
27
20
|
async function ensureDirectoryExists(dirPath) {
|
|
28
21
|
try {
|
|
@@ -33,359 +26,77 @@ async function ensureDirectoryExists(dirPath) {
|
|
|
33
26
|
}
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
async function
|
|
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
|
-
|
|
29
|
+
export async function getAuth0AuthToken(auth0Domain, clientId, clientSecret) {
|
|
60
30
|
try {
|
|
61
|
-
const
|
|
62
|
-
|
|
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`,
|
|
31
|
+
const response = await axios.post(
|
|
32
|
+
`https://${auth0Domain}/oauth/token`,
|
|
70
33
|
{
|
|
71
|
-
client_id:
|
|
72
|
-
|
|
73
|
-
|
|
34
|
+
client_id: clientId,
|
|
35
|
+
client_secret: clientSecret,
|
|
36
|
+
audience: `https://${auth0Domain}/api/v2/`,
|
|
37
|
+
grant_type: 'client_credentials',
|
|
74
38
|
},
|
|
75
39
|
{
|
|
76
40
|
headers: {
|
|
77
|
-
|
|
78
|
-
"Content-Type": "application/json",
|
|
41
|
+
'Content-Type': 'application/json',
|
|
79
42
|
},
|
|
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
|
-
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
43
|
},
|
|
359
|
-
|
|
44
|
+
);
|
|
360
45
|
|
|
361
46
|
const authToken = response.data.access_token;
|
|
362
47
|
// console.log("Auth0 Auth Token:", authToken);
|
|
363
48
|
return authToken;
|
|
364
49
|
} catch (error) {
|
|
365
|
-
console.error(
|
|
50
|
+
console.error(
|
|
51
|
+
'Error fetching Auth0 token:',
|
|
52
|
+
error.response ? error.response.data : error.message,
|
|
53
|
+
);
|
|
366
54
|
}
|
|
367
55
|
}
|
|
368
56
|
|
|
369
|
-
async function configureUI(
|
|
370
|
-
|
|
57
|
+
async function configureUI(
|
|
58
|
+
siteHost,
|
|
59
|
+
coreURL,
|
|
60
|
+
docupaceHost,
|
|
61
|
+
site,
|
|
62
|
+
env,
|
|
63
|
+
auth0Domain,
|
|
64
|
+
auth0ClientId,
|
|
65
|
+
auth0ClientSecret,
|
|
66
|
+
auth0Token,
|
|
67
|
+
vaultSiteSecretsPath,
|
|
68
|
+
imageTag,
|
|
69
|
+
repoPath,
|
|
70
|
+
useS3,
|
|
71
|
+
) {
|
|
72
|
+
console.log(
|
|
73
|
+
`Configuring UI for site: ${site} Host: ${siteHost} in env: ${env}`,
|
|
74
|
+
);
|
|
371
75
|
siteHost = siteHost.replace('https://', '');
|
|
372
76
|
coreURL = coreURL.replace('https://', '');
|
|
373
77
|
|
|
374
|
-
|
|
375
78
|
try {
|
|
376
|
-
const auth0Response = await axios.get(
|
|
377
|
-
|
|
378
|
-
|
|
79
|
+
const auth0Response = await axios.get(
|
|
80
|
+
`https://${auth0Domain}/api/v2/clients`,
|
|
81
|
+
{
|
|
82
|
+
headers: { authorization: `Bearer ${auth0Token}` },
|
|
83
|
+
},
|
|
84
|
+
);
|
|
379
85
|
|
|
380
|
-
const uiClient = auth0Response.data.find(
|
|
86
|
+
const uiClient = auth0Response.data.find(
|
|
87
|
+
(client) => client.name === 'docupace-ui-main',
|
|
88
|
+
);
|
|
381
89
|
const uiAuth0ClientId = uiClient.client_id;
|
|
382
90
|
const uiAuth0ClientSecret = uiClient.client_secret;
|
|
383
91
|
|
|
384
92
|
// Generate Auth0 Secret
|
|
385
|
-
const uiAuth0Secret = crypto
|
|
93
|
+
const uiAuth0Secret = crypto
|
|
94
|
+
.randomBytes(48)
|
|
95
|
+
.toString('base64')
|
|
96
|
+
.replace(/[^a-zA-Z0-9]/g, '');
|
|
386
97
|
|
|
387
98
|
// Prepare data payload
|
|
388
|
-
console.log(
|
|
99
|
+
console.log('Preparing Vault UI data payload...');
|
|
389
100
|
const uiSecretData = JSON.stringify({
|
|
390
101
|
data: {
|
|
391
102
|
AUTH0_CLIENT_ID: uiAuth0ClientId,
|
|
@@ -415,9 +126,28 @@ uiMain:
|
|
|
415
126
|
env:
|
|
416
127
|
AUTH0_CLIENT_SECRET: vault:secret/data/${site}/ui/config#AUTH0_CLIENT_SECRET
|
|
417
128
|
AUTH0_SECRET: vault:secret/data/${site}/ui/config#AUTH0_SECRET
|
|
129
|
+
${
|
|
130
|
+
useS3 === true || useS3 === 'true'
|
|
131
|
+
? `
|
|
132
|
+
AWS_ACCESS_KEY_ID: vault:secret/data/${site}/aws/config#AWS_ACCESS_KEY_ID
|
|
133
|
+
AWS_BUCKET_NAME: vault:secret/data/${site}/aws/config#AWS_BUCKET_NAME
|
|
134
|
+
AWS_SECRET_ACCESS_KEY: vault:secret/data/${site}/aws/config#AWS_SECRET_ACCESS_KEY
|
|
135
|
+
`.trim()
|
|
136
|
+
: ''
|
|
137
|
+
}
|
|
418
138
|
image:
|
|
419
139
|
repository: registry.paperout.com/docupace-ui-main-dev-docker-local/docupace-ui-main
|
|
420
140
|
tag: ${imageTag}
|
|
141
|
+
${
|
|
142
|
+
useS3 === true || useS3 === 'true'
|
|
143
|
+
? `
|
|
144
|
+
serviceAccount:
|
|
145
|
+
create: true
|
|
146
|
+
annotations:
|
|
147
|
+
eks.amazonaws.com/role-arn: arn:aws:iam::902873770924:role/eks-pod-identity-connect-next-${env}-${site}-bucket
|
|
148
|
+
`.trim()
|
|
149
|
+
: ''
|
|
150
|
+
}
|
|
421
151
|
imagePullSecrets:
|
|
422
152
|
- name: jf-artifactory
|
|
423
153
|
ingress:
|
|
@@ -438,7 +168,7 @@ ingress:
|
|
|
438
168
|
- ${siteHost}
|
|
439
169
|
secretName: dp-next-ui-cert
|
|
440
170
|
externalConnectIngress:
|
|
441
|
-
enabled:
|
|
171
|
+
enabled: true
|
|
442
172
|
className: nginx
|
|
443
173
|
annotations:
|
|
444
174
|
cert-manager.io/cluster-issuer: letsencrypt
|
|
@@ -467,57 +197,154 @@ externalConnectIngress:
|
|
|
467
197
|
- ${siteHost}
|
|
468
198
|
secretName: dp-next-ui-cert
|
|
469
199
|
externalConnectService:
|
|
470
|
-
enabled:
|
|
200
|
+
enabled: true
|
|
471
201
|
name: external-connect
|
|
472
202
|
domain: ${docupaceHost}
|
|
473
203
|
`.trim();
|
|
474
204
|
|
|
475
|
-
|
|
476
|
-
console.log("Writing configuration files...");
|
|
205
|
+
console.log('Writing configuration files...');
|
|
477
206
|
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
478
207
|
|
|
479
|
-
await fs.writeFile(
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
208
|
+
await fs.writeFile(
|
|
209
|
+
`${repoPath}/dp/${site}/ui.app.yaml`,
|
|
210
|
+
uiAppYaml,
|
|
211
|
+
(err) => {
|
|
212
|
+
if (err) {
|
|
213
|
+
console.error('Failed to write the file:', err);
|
|
214
|
+
} else {
|
|
215
|
+
console.log('File written successfully.');
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
);
|
|
486
219
|
|
|
487
|
-
await fs.writeFile(
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
220
|
+
await fs.writeFile(
|
|
221
|
+
`${repoPath}/dp/${site}/ui.values.yaml`,
|
|
222
|
+
uiValuesYaml,
|
|
223
|
+
(err) => {
|
|
224
|
+
if (err) {
|
|
225
|
+
console.error('Failed to write the file:', err);
|
|
226
|
+
} else {
|
|
227
|
+
console.log('File written successfully.');
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
);
|
|
231
|
+
console.log('Done!');
|
|
232
|
+
console.log('Updating Core Site Config...');
|
|
233
|
+
await updateCoreSiteConfig(site, env, useS3);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error('Error configuring UI:', error);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export async function cleanAndWritePropertiesFile(configPath, content) {
|
|
240
|
+
try {
|
|
241
|
+
const cleanedContent = content
|
|
242
|
+
.split('\n')
|
|
243
|
+
.map((line) => line.trim())
|
|
244
|
+
.filter((line) => line !== '')
|
|
245
|
+
.join('\n');
|
|
246
|
+
|
|
247
|
+
await fs.writeFile(configPath, cleanedContent, 'utf8');
|
|
248
|
+
console.log(`Cleaned and written file to: ${configPath}`);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error('Error writing properties file:', error.message);
|
|
251
|
+
process.exit(1);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export async function updateCoreSiteConfig(site, env, useS3) {
|
|
256
|
+
try {
|
|
257
|
+
const coreSiteEnv = coreSiteEnvMap[env];
|
|
258
|
+
|
|
259
|
+
const coreSiteConfigRepoPath = await cloneRepository(
|
|
260
|
+
`${coreSiteEnv}-site-settings`,
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const configPath = path.join(
|
|
264
|
+
`${coreSiteEnv}-site-settings`,
|
|
265
|
+
site.toUpperCase(),
|
|
266
|
+
'docucore-nextUI.properties',
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
let siteAWSSecrets = null;
|
|
270
|
+
|
|
271
|
+
if (useS3 === true || useS3 === 'true') {
|
|
272
|
+
const siteAWSSecretsPath = getVaultSecretsConfigs(site).awsSecretsPath;
|
|
273
|
+
siteAWSSecrets = await getVaultSecrets(siteAWSSecretsPath);
|
|
274
|
+
console.log(`siteAWSSecretsPath => ${siteAWSSecretsPath}`);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const coreSiteConfig = `
|
|
278
|
+
${
|
|
279
|
+
siteAWSSecrets
|
|
280
|
+
? `
|
|
281
|
+
com.docupace.imports.files.FilesImportConfig.aws.accessKeyId=${siteAWSSecrets.AWS_ACCESS_KEY_ID}
|
|
282
|
+
com.docupace.imports.files.FilesImportConfig.aws.accessKeySecret=${siteAWSSecrets.AWS_SECRET_ACCESS_KEY}
|
|
283
|
+
com.docupace.imports.files.FilesImportConfig.aws.region=${siteAWSSecrets.AWS_REGION}
|
|
284
|
+
`.trim()
|
|
285
|
+
: ''
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
|
|
289
|
+
await fs.ensureDir(path.join(coreSiteConfigRepoPath, site.toUpperCase()));
|
|
290
|
+
await cleanAndWritePropertiesFile(configPath, coreSiteConfig);
|
|
291
|
+
await pushDeployConfig(
|
|
292
|
+
coreSiteConfigRepoPath,
|
|
293
|
+
`Core config: docucore-nextUI.properties for site: (${site.toUpperCase()}) update in env: (${env})`,
|
|
294
|
+
);
|
|
495
295
|
} catch (error) {
|
|
496
|
-
console.error(
|
|
296
|
+
console.error('Error:', error.message);
|
|
297
|
+
process.exit(1);
|
|
497
298
|
}
|
|
498
299
|
}
|
|
499
300
|
|
|
500
|
-
async function configureGraphQLServer(
|
|
301
|
+
async function configureGraphQLServer(
|
|
302
|
+
siteHost,
|
|
303
|
+
coreURL,
|
|
304
|
+
docupaceHost,
|
|
305
|
+
site,
|
|
306
|
+
env,
|
|
307
|
+
auth0Domain,
|
|
308
|
+
auth0ClientId,
|
|
309
|
+
auth0ClientSecret,
|
|
310
|
+
auth0Token,
|
|
311
|
+
vaultSiteSecretsPath,
|
|
312
|
+
imageTag,
|
|
313
|
+
standardConfigRemoteBranch,
|
|
314
|
+
repoPath,
|
|
315
|
+
commonSecrets,
|
|
316
|
+
) {
|
|
501
317
|
siteHost = siteHost.replace('https://', '');
|
|
502
318
|
coreURL = coreURL.replace('https://', '');
|
|
503
|
-
console.log(
|
|
319
|
+
console.log(
|
|
320
|
+
`Configuring GraphQL Server for site: ${site} Host: ${siteHost} in env: ${env}`,
|
|
321
|
+
);
|
|
504
322
|
|
|
505
323
|
try {
|
|
506
|
-
const auth0Response = await axios.get(
|
|
507
|
-
|
|
508
|
-
|
|
324
|
+
const auth0Response = await axios.get(
|
|
325
|
+
`https://${auth0Domain}/api/v2/clients`,
|
|
326
|
+
{
|
|
327
|
+
headers: { authorization: `Bearer ${auth0Token}` },
|
|
328
|
+
},
|
|
329
|
+
);
|
|
509
330
|
|
|
510
|
-
const graphQLServerClient = auth0Response.data.find(
|
|
511
|
-
|
|
331
|
+
const graphQLServerClient = auth0Response.data.find(
|
|
332
|
+
(client) => client.name === 'docupace-graphql',
|
|
333
|
+
);
|
|
334
|
+
const graphQLServerClientCredentials = auth0Response.data.find(
|
|
335
|
+
(client) => client.name === 'docupace-graphql-client-credentials',
|
|
336
|
+
);
|
|
512
337
|
|
|
513
338
|
const graphQLServerAuth0ClientId = graphQLServerClient.client_id;
|
|
514
339
|
const graphQLServerAuth0ClientSecret = graphQLServerClient.client_secret;
|
|
515
340
|
|
|
516
|
-
const graphQLServerCCAuth0ClientId =
|
|
517
|
-
|
|
341
|
+
const graphQLServerCCAuth0ClientId =
|
|
342
|
+
graphQLServerClientCredentials.client_id;
|
|
343
|
+
const graphQLServerCCAuth0ClientSecret =
|
|
344
|
+
graphQLServerClientCredentials.client_secret;
|
|
518
345
|
|
|
519
346
|
// Prepare data payload
|
|
520
|
-
console.log(
|
|
347
|
+
console.log('Preparing Vault GraphQL Server data payload...');
|
|
521
348
|
const graphQLServerSecretData = JSON.stringify({
|
|
522
349
|
data: {
|
|
523
350
|
AUTH0_CLIENT_ID: graphQLServerAuth0ClientId,
|
|
@@ -580,105 +407,129 @@ ingress:
|
|
|
580
407
|
`.trim();
|
|
581
408
|
|
|
582
409
|
// Write configuration files
|
|
583
|
-
console.log(
|
|
410
|
+
console.log('Writing ArgoCD GraphQL Server configuration files...');
|
|
584
411
|
await ensureDirectoryExists(path.resolve(`${repoPath}/dp/${site}`));
|
|
585
412
|
|
|
586
|
-
await fs.writeFile(
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
413
|
+
await fs.writeFile(
|
|
414
|
+
`${repoPath}/dp/${site}/graphql-server.app.yaml`,
|
|
415
|
+
graphQLServerAppYaml,
|
|
416
|
+
(err) => {
|
|
417
|
+
if (err) {
|
|
418
|
+
console.error('Failed to write the file:', err);
|
|
419
|
+
} else {
|
|
420
|
+
console.log('File written successfully.');
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
);
|
|
593
424
|
|
|
594
|
-
await fs.writeFile(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
425
|
+
await fs.writeFile(
|
|
426
|
+
`${repoPath}/dp/${site}/graphql-server.values.yaml`,
|
|
427
|
+
graphQLServerValuesYaml,
|
|
428
|
+
(err) => {
|
|
429
|
+
if (err) {
|
|
430
|
+
console.error('Failed to write the file:', err);
|
|
431
|
+
} else {
|
|
432
|
+
console.log('File written successfully.');
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
);
|
|
436
|
+
console.log('Done!');
|
|
602
437
|
} catch (error) {
|
|
603
|
-
console.error(
|
|
438
|
+
console.error('Error configuring GraphQL Server:', error);
|
|
604
439
|
}
|
|
605
440
|
}
|
|
606
441
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
442
|
+
export async function configureFromSite(
|
|
443
|
+
fromSite,
|
|
444
|
+
toSite,
|
|
445
|
+
fromEnv,
|
|
446
|
+
toEnv,
|
|
447
|
+
deployUI,
|
|
448
|
+
deployGraphQLServer,
|
|
449
|
+
useNewDomain,
|
|
450
|
+
useS3,
|
|
451
|
+
) {
|
|
452
|
+
console.log(
|
|
453
|
+
`Configuring Auth0 tenants and ArgoCD apps for site: ${toSite} in env: ${toEnv} from site: ${fromSite}`,
|
|
454
|
+
);
|
|
610
455
|
// Common Secrets
|
|
611
456
|
const commonSecretsPath = getVaultSecretsConfigs(toSite).commonSecretsPath;
|
|
612
|
-
console.log(`commonSecretsPath => ${commonSecretsPath}`)
|
|
457
|
+
console.log(`commonSecretsPath => ${commonSecretsPath}`);
|
|
613
458
|
const commonSecrets = await getVaultSecrets(commonSecretsPath);
|
|
614
459
|
|
|
615
460
|
// Site Common Secrets
|
|
616
|
-
const siteCommonSecretsPath =
|
|
617
|
-
|
|
461
|
+
const siteCommonSecretsPath =
|
|
462
|
+
getVaultSecretsConfigs(toSite).siteCommonSecretsPath;
|
|
463
|
+
console.log(`siteCommonSecretsPath => ${siteCommonSecretsPath}`);
|
|
618
464
|
const siteCommonSecrets = await getVaultSecrets(siteCommonSecretsPath);
|
|
619
465
|
|
|
620
|
-
const auth0Domain = `docupace-${toEnv}-${toSite}.us.auth0.com
|
|
466
|
+
const auth0Domain = `docupace-${toEnv}-${toSite}.us.auth0.com`;
|
|
621
467
|
const auth0ClientId = siteCommonSecrets.AUTH0_CLIENT_ID;
|
|
622
468
|
const auth0ClientSecret = siteCommonSecrets.AUTH0_CLIENT_SECRET;
|
|
623
|
-
const auth0Token = await getAuth0AuthToken(
|
|
469
|
+
const auth0Token = await getAuth0AuthToken(
|
|
470
|
+
auth0Domain,
|
|
471
|
+
auth0ClientId,
|
|
472
|
+
auth0ClientSecret,
|
|
473
|
+
);
|
|
624
474
|
|
|
625
475
|
// UI app
|
|
626
476
|
const uiSecretsPath = getVaultSecretsConfigs(toSite).uiSecretsPath;
|
|
627
|
-
console.log(`uiSecretsPath => ${uiSecretsPath}`)
|
|
477
|
+
console.log(`uiSecretsPath => ${uiSecretsPath}`);
|
|
628
478
|
|
|
629
479
|
// GraphQL-Server app
|
|
630
|
-
const graphqlSecretsPath =
|
|
480
|
+
const graphqlSecretsPath =
|
|
481
|
+
getVaultSecretsConfigs(toSite).graphqlServerSecretsPath;
|
|
631
482
|
console.log(`graphqlSecretsPath => ${graphqlSecretsPath}`);
|
|
632
483
|
|
|
633
|
-
let repoPathFromEnv =
|
|
634
|
-
let repoPathToEnv =
|
|
484
|
+
let repoPathFromEnv = '';
|
|
485
|
+
let repoPathToEnv = '';
|
|
635
486
|
// Clone repositories
|
|
636
|
-
if (
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}else {
|
|
640
|
-
|
|
641
|
-
|
|
487
|
+
if (fromEnv === toEnv) {
|
|
488
|
+
repoPathFromEnv = await cloneEnvRepository(fromEnv);
|
|
489
|
+
repoPathToEnv = repoPathFromEnv;
|
|
490
|
+
} else {
|
|
491
|
+
repoPathFromEnv = await cloneEnvRepository(fromEnv);
|
|
492
|
+
repoPathToEnv = await cloneEnvRepository(toEnv);
|
|
642
493
|
}
|
|
643
494
|
|
|
644
495
|
//TODO: clone fromEnv and toEnv. replace above with this
|
|
645
496
|
|
|
646
|
-
const auth0RepoPath = await cloneRepository('auth0-site-setup');
|
|
497
|
+
// const auth0RepoPath = await cloneRepository('auth0-site-setup');
|
|
647
498
|
|
|
648
499
|
// Read deploy configs
|
|
649
|
-
const { deployConfig: deployUIConfig } = await readDeployConfig(
|
|
500
|
+
const { deployConfig: deployUIConfig } = await readDeployConfig(
|
|
501
|
+
'ui',
|
|
502
|
+
fromEnv,
|
|
503
|
+
fromSite,
|
|
504
|
+
'values',
|
|
505
|
+
);
|
|
650
506
|
const uiImageTag = deployUIConfig.image.tag;
|
|
651
507
|
|
|
652
|
-
const { deployConfig: deployGraphQLServerConfig } = await readDeployConfig(
|
|
508
|
+
const { deployConfig: deployGraphQLServerConfig } = await readDeployConfig(
|
|
509
|
+
'graphql-server',
|
|
510
|
+
fromEnv,
|
|
511
|
+
fromSite,
|
|
512
|
+
'values',
|
|
513
|
+
);
|
|
653
514
|
const graphqlImageTag = deployGraphQLServerConfig.image.tag;
|
|
654
|
-
const graphqlStandardConfigRemoteBranch =
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
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}`);
|
|
515
|
+
const graphqlStandardConfigRemoteBranch =
|
|
516
|
+
deployGraphQLServerConfig.graphqlServer.standardConfigRemoteBranch;
|
|
517
|
+
|
|
518
|
+
console.log(
|
|
519
|
+
`Copying Latest UI Image Tag: ${deployUIConfig.image.tag} from site: ${fromSite} to site: ${toSite}`,
|
|
520
|
+
);
|
|
521
|
+
console.log(
|
|
522
|
+
`Copying Latest GraphQL Server Image Tag: ${deployGraphQLServerConfig.image.tag} from site: ${fromSite} to site: ${toSite}`,
|
|
523
|
+
);
|
|
669
524
|
|
|
670
525
|
const envConfig = environmentConfig[toEnv];
|
|
671
526
|
|
|
672
|
-
let CORE_URL,
|
|
673
|
-
SITE_HOST,
|
|
674
|
-
CORE_API_CONTEXT,
|
|
675
|
-
CONNECT_URL,
|
|
676
|
-
DOCUPACE_HOST;
|
|
527
|
+
let CORE_URL, SITE_HOST, CORE_API_CONTEXT, CONNECT_URL, DOCUPACE_HOST;
|
|
677
528
|
if (useNewDomain) {
|
|
678
529
|
const newUrl = envConfig.newUrl(toSite);
|
|
679
530
|
CORE_URL = `${newUrl}/core`;
|
|
680
531
|
SITE_HOST = newUrl;
|
|
681
|
-
CORE_API_CONTEXT =
|
|
532
|
+
CORE_API_CONTEXT = 'core';
|
|
682
533
|
CONNECT_URL = `${newUrl}/connect`;
|
|
683
534
|
DOCUPACE_HOST = envConfig.docupaceHost();
|
|
684
535
|
} else {
|
|
@@ -689,27 +540,42 @@ export async function configureFromSite(fromSite, toSite, fromEnv,toEnv, deployU
|
|
|
689
540
|
CONNECT_URL = `${oldUrl}_ui`;
|
|
690
541
|
}
|
|
691
542
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
543
|
+
if (deployUI === true || deployUI === 'true') {
|
|
544
|
+
await configureUI(
|
|
545
|
+
SITE_HOST,
|
|
546
|
+
CORE_URL,
|
|
547
|
+
DOCUPACE_HOST,
|
|
548
|
+
toSite,
|
|
549
|
+
toEnv,
|
|
550
|
+
auth0Domain,
|
|
551
|
+
auth0ClientId,
|
|
552
|
+
auth0ClientSecret,
|
|
553
|
+
auth0Token,
|
|
554
|
+
uiSecretsPath,
|
|
555
|
+
uiImageTag,
|
|
556
|
+
repoPathToEnv,
|
|
557
|
+
useS3,
|
|
558
|
+
);
|
|
697
559
|
}
|
|
698
560
|
|
|
699
|
-
await configureGraphQLServer(
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
561
|
+
await configureGraphQLServer(
|
|
562
|
+
SITE_HOST,
|
|
563
|
+
CORE_URL,
|
|
564
|
+
DOCUPACE_HOST,
|
|
565
|
+
toSite,
|
|
566
|
+
toEnv,
|
|
567
|
+
auth0Domain,
|
|
568
|
+
auth0ClientId,
|
|
569
|
+
auth0ClientSecret,
|
|
570
|
+
auth0Token,
|
|
571
|
+
graphqlSecretsPath,
|
|
572
|
+
graphqlImageTag,
|
|
573
|
+
graphqlStandardConfigRemoteBranch,
|
|
574
|
+
repoPathToEnv,
|
|
575
|
+
commonSecrets,
|
|
576
|
+
);
|
|
577
|
+
await pushDeployConfig(
|
|
578
|
+
repoPathToEnv,
|
|
579
|
+
`Config update for ${toSite} from ${fromSite} with UI: ${uiImageTag} and GraphQL: ${graphqlImageTag}`,
|
|
580
|
+
);
|
|
715
581
|
}
|