Skip to content

Commit 1ba6014

Browse files
authoredMay 27, 2025··
fix: export database options and customScripts safely (#1095)
* fix: handle optional database options and customScripts safely * fix: ensure options are handled correctly when undefined in database handlers * fix: format path construction for improved readability in database dump tests
1 parent dd872fd commit 1ba6014

File tree

4 files changed

+69
-13
lines changed

4 files changed

+69
-13
lines changed
 

‎src/context/directory/handlers/databases.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ function getDatabase(
5454
const database = {
5555
...metaData,
5656
options: {
57-
//@ts-ignore because this code exists currently, but still needs to be understood if it is correct or not
58-
...metaData.options,
59-
//@ts-ignore because this code exists currently, but still needs to be understood if it is correct or not
60-
...(metaData.customScripts && { customScripts: metaData.customScripts }),
57+
// @ts-ignore because this code exists currently, but still needs to be understood if it is correct or not
58+
...(metaData.options || {}),
59+
// @ts-ignore because this code exists currently, but still needs to be understood if it is correct or not
60+
...(metaData?.customScripts && { customScripts: metaData?.customScripts }),
6161
},
6262
};
6363

6464
// If any customScripts configured then load content of files
65-
if (database.options.customScripts) {
65+
if (database.options?.customScripts) {
6666
Object.entries(database.options.customScripts).forEach(([name, script]: [string, string]) => {
6767
if (!constants.DATABASE_SCRIPTS.includes(name)) {
6868
// skip invalid keys in customScripts object
@@ -128,18 +128,18 @@ async function dump(context: DirectoryContext): Promise<void> {
128128
),
129129
}),
130130
options: {
131-
...database.options,
131+
...(database.options || {}),
132132
// customScripts option only written if there are scripts
133-
...(database.options.customScripts && {
133+
...(database.options?.customScripts && {
134134
customScripts: Object.entries(database.options.customScripts)
135-
//@ts-ignore because we'll fix this in subsequent PR
135+
// @ts-ignore because we'll fix this in subsequent PR
136136
.sort(sortCustomScripts)
137137
.reduce((scripts, [name, script]) => {
138138
// Dump custom script to file
139139
const scriptName = sanitize(`${name}.js`);
140140
const scriptFile = path.join(dbFolder, scriptName);
141141
log.info(`Writing ${scriptFile}`);
142-
//@ts-ignore because we'll fix this in subsequent PR
142+
// @ts-ignore because we'll fix this in subsequent PR
143143
fs.writeFileSync(scriptFile, script);
144144
scripts[name] = `./${scriptName}`;
145145
return scripts;

‎src/context/yaml/handlers/databases.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ async function parse(context: YAMLContext): Promise<ParsedDatabases> {
1919
...databases.map((database) => ({
2020
...database,
2121
options: {
22-
...database.options,
22+
...(database.options || {}),
2323
// customScripts option only written if there are scripts
24-
...(database.options.customScripts && {
24+
...(database.options?.customScripts && {
2525
customScripts: Object.entries(database.options.customScripts).reduce(
2626
(scripts, [name, script]) => ({
2727
...scripts,
@@ -54,9 +54,9 @@ async function dump(context: YAMLContext): Promise<ParsedDatabases> {
5454
enabled_clients: mapClientID2NameSorted(database.enabled_clients, clients || []),
5555
}),
5656
options: {
57-
...database.options,
57+
...(database.options || {}),
5858
// customScripts option only written if there are scripts
59-
...(database.options.customScripts && {
59+
...(database.options?.customScripts && {
6060
customScripts: Object.entries(database.options.customScripts)
6161
//@ts-ignore because we'll fix this in subsequent PR
6262
.sort(sortCustomScripts)

‎test/context/directory/databases.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,31 @@ describe('#directory context databases', () => {
327327
scriptValidate
328328
);
329329
});
330+
331+
it('should dump database with undefined options', async () => {
332+
cleanThenMkdir(dbDumpDir);
333+
const context = new Context({ AUTH0_INPUT_FILE: dbDumpDir }, mockMgmtClient());
334+
335+
context.assets.databases = [
336+
{
337+
name: 'users-no-options',
338+
enabled_clients: [],
339+
// options field intentionally missing
340+
strategy: 'auth0',
341+
},
342+
];
343+
344+
await handler.dump(context);
345+
const scriptsFolder = path.join(
346+
dbDumpDir,
347+
constants.DATABASE_CONNECTIONS_DIRECTORY,
348+
'users-no-options'
349+
);
350+
expect(loadJSON(path.join(scriptsFolder, 'database.json'))).to.deep.equal({
351+
name: 'users-no-options',
352+
enabled_clients: [],
353+
options: {}, // should be empty object when options is undefined
354+
strategy: 'auth0',
355+
});
356+
});
330357
});

‎test/context/yaml/databases.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,33 @@ describe('#YAML context databases', () => {
256256
scriptValidate
257257
);
258258
});
259+
260+
it('should dump database with undefined options', async () => {
261+
cleanThenMkdir(dbDumpDir);
262+
const context = new Context(
263+
{ AUTH0_INPUT_FILE: path.join(dbDumpDir, 'tenant.yaml') },
264+
mockMgmtClient()
265+
);
266+
267+
context.assets.databases = [
268+
{
269+
name: 'users-no-options',
270+
enabled_clients: [],
271+
// options field intentionally missing
272+
strategy: 'auth0',
273+
},
274+
];
275+
276+
const dumped = await handler.dump(context);
277+
expect(dumped).to.deep.equal({
278+
databases: [
279+
{
280+
name: 'users-no-options',
281+
enabled_clients: [],
282+
options: {}, // should be empty object when options is undefined
283+
strategy: 'auth0',
284+
},
285+
],
286+
});
287+
});
259288
});

0 commit comments

Comments
 (0)
Please sign in to comment.