Skip to content

Commit dfe2588

Browse files
committed
Refactor API Schema and validation
- /schema now returns full openapi/swagger schema - That schema is used to validate incoming requests - And used as a contract in future integration tests - Moved route files up one level - Fixed incorrect 404 reponses when getting objects - Fixed saving new objects and passing jsonschemavalidation
1 parent 63d06da commit dfe2588

File tree

123 files changed

+5363
-2574
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+5363
-2574
lines changed

backend/.vscode/settings.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

backend/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ app.use(function (req, res, next) {
5252
});
5353

5454
app.use(require('./lib/express/jwt')());
55-
app.use('/', require('./routes/api/main'));
55+
app.use('/', require('./routes/main'));
5656

5757
// production error handler
5858
// no stacktraces leaked to user

backend/index.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
#!/usr/bin/env node
22

3+
const schema = require('./schema');
34
const logger = require('./logger').global;
45

56
async function appStart () {
67
const migrate = require('./migrate');
78
const setup = require('./setup');
89
const app = require('./app');
9-
const apiValidator = require('./lib/validator/api');
1010
const internalCertificate = require('./internal/certificate');
1111
const internalIpRanges = require('./internal/ip_ranges');
1212

1313
return migrate.latest()
1414
.then(setup)
15-
.then(() => {
16-
return apiValidator.loadSchemas;
17-
})
15+
.then(schema.getCompiledSchema)
1816
.then(internalIpRanges.fetch)
1917
.then(() => {
20-
2118
internalCertificate.initTimer();
2219
internalIpRanges.initTimer();
2320

@@ -34,7 +31,7 @@ async function appStart () {
3431
});
3532
})
3633
.catch((err) => {
37-
logger.error(err.message);
34+
logger.error(err.message, err);
3835
setTimeout(appStart, 1000);
3936
});
4037
}

backend/internal/access-list.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ const internalAccessList = {
269269
return query.then(utils.omitRow(omissions()));
270270
})
271271
.then((row) => {
272-
if (!row) {
272+
if (!row || !row.id) {
273273
throw new error.ItemNotFoundError(data.id);
274274
}
275275
if (!skip_masking && typeof row.items !== 'undefined' && row.items) {
@@ -296,7 +296,7 @@ const internalAccessList = {
296296
return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items', 'clients']});
297297
})
298298
.then((row) => {
299-
if (!row) {
299+
if (!row || !row.id) {
300300
throw new error.ItemNotFoundError(data.id);
301301
}
302302

backend/internal/certificate.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ const internalCertificate = {
323323
return query.then(utils.omitRow(omissions()));
324324
})
325325
.then((row) => {
326-
if (!row) {
326+
if (!row || !row.id) {
327327
throw new error.ItemNotFoundError(data.id);
328328
}
329329
// Custom omissions
@@ -412,7 +412,7 @@ const internalCertificate = {
412412
return internalCertificate.get(access, {id: data.id});
413413
})
414414
.then((row) => {
415-
if (!row) {
415+
if (!row || !row.id) {
416416
throw new error.ItemNotFoundError(data.id);
417417
}
418418

backend/internal/dead-host.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ const internalDeadHost = {
4848
data.owner_user_id = access.token.getUserId(1);
4949
data = internalHost.cleanSslHstsData(data);
5050

51+
// Fix for db field not having a default value
52+
// for this optional field.
53+
if (typeof data.advanced_config === 'undefined') {
54+
data.advanced_config = '';
55+
}
56+
5157
return deadHostModel
5258
.query()
5359
.insertAndFetch(data)
@@ -233,7 +239,7 @@ const internalDeadHost = {
233239
return query.then(utils.omitRow(omissions()));
234240
})
235241
.then((row) => {
236-
if (!row) {
242+
if (!row || !row.id) {
237243
throw new error.ItemNotFoundError(data.id);
238244
}
239245
// Custom omissions
@@ -257,7 +263,7 @@ const internalDeadHost = {
257263
return internalDeadHost.get(access, {id: data.id});
258264
})
259265
.then((row) => {
260-
if (!row) {
266+
if (!row || !row.id) {
261267
throw new error.ItemNotFoundError(data.id);
262268
}
263269

@@ -305,7 +311,7 @@ const internalDeadHost = {
305311
});
306312
})
307313
.then((row) => {
308-
if (!row) {
314+
if (!row || !row.id) {
309315
throw new error.ItemNotFoundError(data.id);
310316
} else if (row.enabled) {
311317
throw new error.ValidationError('Host is already enabled');
@@ -351,7 +357,7 @@ const internalDeadHost = {
351357
return internalDeadHost.get(access, {id: data.id});
352358
})
353359
.then((row) => {
354-
if (!row) {
360+
if (!row || !row.id) {
355361
throw new error.ItemNotFoundError(data.id);
356362
} else if (!row.enabled) {
357363
throw new error.ValidationError('Host is already disabled');

backend/internal/proxy-host.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ const internalProxyHost = {
4848
data.owner_user_id = access.token.getUserId(1);
4949
data = internalHost.cleanSslHstsData(data);
5050

51+
// Fix for db field not having a default value
52+
// for this optional field.
53+
if (typeof data.advanced_config === 'undefined') {
54+
data.advanced_config = '';
55+
}
56+
5157
return proxyHostModel
5258
.query()
5359
.insertAndFetch(data)
@@ -239,7 +245,7 @@ const internalProxyHost = {
239245
return query.then(utils.omitRow(omissions()));
240246
})
241247
.then((row) => {
242-
if (!row) {
248+
if (!row || !row.id) {
243249
throw new error.ItemNotFoundError(data.id);
244250
}
245251
row = internalHost.cleanRowCertificateMeta(row);
@@ -264,7 +270,7 @@ const internalProxyHost = {
264270
return internalProxyHost.get(access, {id: data.id});
265271
})
266272
.then((row) => {
267-
if (!row) {
273+
if (!row || !row.id) {
268274
throw new error.ItemNotFoundError(data.id);
269275
}
270276

@@ -312,7 +318,7 @@ const internalProxyHost = {
312318
});
313319
})
314320
.then((row) => {
315-
if (!row) {
321+
if (!row || !row.id) {
316322
throw new error.ItemNotFoundError(data.id);
317323
} else if (row.enabled) {
318324
throw new error.ValidationError('Host is already enabled');
@@ -358,7 +364,7 @@ const internalProxyHost = {
358364
return internalProxyHost.get(access, {id: data.id});
359365
})
360366
.then((row) => {
361-
if (!row) {
367+
if (!row || !row.id) {
362368
throw new error.ItemNotFoundError(data.id);
363369
} else if (!row.enabled) {
364370
throw new error.ValidationError('Host is already disabled');

backend/internal/redirection-host.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ const internalRedirectionHost = {
4848
data.owner_user_id = access.token.getUserId(1);
4949
data = internalHost.cleanSslHstsData(data);
5050

51+
// Fix for db field not having a default value
52+
// for this optional field.
53+
if (typeof data.advanced_config === 'undefined') {
54+
data.advanced_config = '';
55+
}
56+
5157
return redirectionHostModel
5258
.query()
5359
.insertAndFetch(data)
@@ -232,7 +238,7 @@ const internalRedirectionHost = {
232238
return query.then(utils.omitRow(omissions()));
233239
})
234240
.then((row) => {
235-
if (!row) {
241+
if (!row || !row.id) {
236242
throw new error.ItemNotFoundError(data.id);
237243
}
238244
row = internalHost.cleanRowCertificateMeta(row);
@@ -257,7 +263,7 @@ const internalRedirectionHost = {
257263
return internalRedirectionHost.get(access, {id: data.id});
258264
})
259265
.then((row) => {
260-
if (!row) {
266+
if (!row || !row.id) {
261267
throw new error.ItemNotFoundError(data.id);
262268
}
263269

@@ -305,7 +311,7 @@ const internalRedirectionHost = {
305311
});
306312
})
307313
.then((row) => {
308-
if (!row) {
314+
if (!row || !row.id) {
309315
throw new error.ItemNotFoundError(data.id);
310316
} else if (row.enabled) {
311317
throw new error.ValidationError('Host is already enabled');
@@ -351,7 +357,7 @@ const internalRedirectionHost = {
351357
return internalRedirectionHost.get(access, {id: data.id});
352358
})
353359
.then((row) => {
354-
if (!row) {
360+
if (!row || !row.id) {
355361
throw new error.ItemNotFoundError(data.id);
356362
} else if (!row.enabled) {
357363
throw new error.ValidationError('Host is already disabled');

backend/internal/stream.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const internalStream = {
128128
return query.then(utils.omitRow(omissions()));
129129
})
130130
.then((row) => {
131-
if (!row) {
131+
if (!row || !row.id) {
132132
throw new error.ItemNotFoundError(data.id);
133133
}
134134
// Custom omissions
@@ -152,7 +152,7 @@ const internalStream = {
152152
return internalStream.get(access, {id: data.id});
153153
})
154154
.then((row) => {
155-
if (!row) {
155+
if (!row || !row.id) {
156156
throw new error.ItemNotFoundError(data.id);
157157
}
158158

@@ -200,7 +200,7 @@ const internalStream = {
200200
});
201201
})
202202
.then((row) => {
203-
if (!row) {
203+
if (!row || !row.id) {
204204
throw new error.ItemNotFoundError(data.id);
205205
} else if (row.enabled) {
206206
throw new error.ValidationError('Host is already enabled');
@@ -246,7 +246,7 @@ const internalStream = {
246246
return internalStream.get(access, {id: data.id});
247247
})
248248
.then((row) => {
249-
if (!row) {
249+
if (!row || !row.id) {
250250
throw new error.ItemNotFoundError(data.id);
251251
} else if (!row.enabled) {
252252
throw new error.ValidationError('Host is already disabled');

backend/internal/user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ const internalUser = {
194194
return query.then(utils.omitRow(omissions()));
195195
})
196196
.then((row) => {
197-
if (!row) {
197+
if (!row || !row.id) {
198198
throw new error.ItemNotFoundError(data.id);
199199
}
200200
// Custom omissions

0 commit comments

Comments
 (0)