Skip to content

Commit 4bd2755

Browse files
committed
Merge branch 'dev' into refactor/domain-challenge
2 parents cf3249c + 37e9d50 commit 4bd2755

31 files changed

+743
-852
lines changed

.circleci/config.yml

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
version: 2
22
defaults: &defaults
33
docker:
4-
- image: circleci/python:2.7-stretch-browsers
4+
- image: cimg/python:3.11.0-browsers
55
install_dependency: &install_dependency
66
name: Installation of build and deployment dependencies.
77
command: |
8+
sudo apt update
89
sudo apt install jq
9-
sudo pip install awscli --upgrade
10-
sudo pip install docker-compose
10+
sudo apt install python3-pip
11+
sudo pip3 install awscli --upgrade
12+
sudo pip3 install docker-compose
1113
install_deploysuite: &install_deploysuite
1214
name: Installation of install_deploysuite.
1315
command: |
@@ -16,10 +18,10 @@ install_deploysuite: &install_deploysuite
1618
cp ./../buildscript/buildenv.sh .
1719
cp ./../buildscript/awsconfiguration.sh .
1820
restore_cache_settings_for_build: &restore_cache_settings_for_build
19-
key: docker-node-modules-{{ checksum "package-lock.json" }}
21+
key: docker-node-modules-{{ checksum "yarn.lock" }}
2022

2123
save_cache_settings: &save_cache_settings
22-
key: docker-node-modules-{{ checksum "package-lock.json" }}
24+
key: docker-node-modules-{{ checksum "yarn.lock" }}
2325
paths:
2426
- node_modules
2527

@@ -69,9 +71,7 @@ workflows:
6971
filters:
7072
branches:
7173
only:
72-
- develop
73-
- feat/phase-extension
74-
- feat/tracing
74+
- dev
7575

7676
# Production builds are exectuted only on tagged commits to the
7777
# master branch.

.vscode/settings.json

+4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"editor.defaultFormatter": "standard.vscode-standard",
3+
<<<<<<< HEAD
34
"standard.autoFixOnSave": true,
45
"[javascript]": {
56
"editor.defaultFormatter": "esbenp.prettier-vscode"
67
}
8+
=======
9+
"standard.autoFixOnSave": true
10+
>>>>>>> dev
711
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ You can find sample `.env` files inside the `/docs` directory.
102102
1. 📦 Install npm dependencies
103103

104104
```bash
105-
npm install
105+
yarn install
106106
```
107107

108108
2. ⚙ Local config

app-constants.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const validChallengeParams = {
4545
StartDate: "startDate",
4646
ProjectId: "projectId",
4747
Name: "name",
48+
Type: "type",
49+
NumOfSubmissions: "numOfSubmissions",
50+
NumOfRegistrants: "numOfRegistrants",
51+
Status: "status",
4852
TypeId: "typeId",
4953
Prizes: "overview.totalPrizes",
5054
};
@@ -64,15 +68,19 @@ const Topics = {
6468
ChallengeDeleted: "challenge.notification.delete",
6569
ChallengeTypeCreated: "test.new.bus.events", // 'challenge.action.type.created',
6670
ChallengeTypeUpdated: "test.new.bus.events", // 'challenge.action.type.updated',
71+
ChallengeTypeDeleted: "test.new.bus.events", // 'challenge.action.type.deleted',
72+
ChallengeTrackCreated: "test.new.bus.events", // 'challenge.action.track.created',
73+
ChallengeTrackUpdated: "test.new.bus.events", // 'challenge.action.track.updated',
74+
ChallengeTrackDeleted: "test.new.bus.events", // 'challenge.action.track.deleted',
6775
ChallengePhaseCreated: "test.new.bus.events", // 'challenge.action.phase.created',
6876
ChallengePhaseUpdated: "test.new.bus.events", // 'challenge.action.phase.updated',
6977
ChallengePhaseDeleted: "test.new.bus.events", // 'challenge.action.phase.deleted',
7078
TimelineTemplateCreated: "test.new.bus.events", // 'challenge.action.timeline.template.created',
7179
TimelineTemplateUpdated: "test.new.bus.events", // 'challenge.action.timeline.template.updated',
7280
TimelineTemplateDeleted: "test.new.bus.events", // 'challenge.action.timeline.template.deleted',
73-
ChallengeTimelineTemplateCreated: "test.new.bus.events", // 'challenge.action.type.timeline.template.created',
74-
ChallengeTimelineTemplateUpdated: "test.new.bus.events", // 'challenge.action.type.timeline.template.updated',
75-
ChallengeTimelineTemplateDeleted: "test.new.bus.events", // 'challenge.action.type.timeline.template.deleted'
81+
ChallengeTypeTimelineTemplateCreated: "test.new.bus.events", // 'challenge.action.type.timeline.template.created',
82+
ChallengeTypeTimelineTemplateUpdated: "test.new.bus.events", // 'challenge.action.type.timeline.template.updated',
83+
ChallengeTypeTimelineTemplateDeleted: "test.new.bus.events", // 'challenge.action.type.timeline.template.deleted'
7684
ChallengeAttachmentCreated: "test.new.bus.events", // 'challenge.action.attachment.created',
7785
ChallengeAttachmentUpdated: "test.new.bus.events", // 'challenge.action.attachment.updated',
7886
ChallengeAttachmentDeleted: "test.new.bus.events", // 'challenge.action.attachment.deleted',

app-routes.js

+100-102
Original file line numberDiff line numberDiff line change
@@ -2,125 +2,123 @@
22
* Configure all routes for express app
33
*/
44

5-
const _ = require('lodash')
6-
const config = require('config')
7-
const HttpStatus = require('http-status-codes')
8-
const helper = require('./src/common/helper')
9-
const errors = require('./src/common/errors')
10-
const routes = require('./src/routes')
11-
const authenticator = require('tc-core-library-js').middleware.jwtAuthenticator
12-
13-
const AWSXRay = require('aws-xray-sdk')
5+
const _ = require("lodash");
6+
const config = require("config");
7+
const HttpStatus = require("http-status-codes");
8+
const helper = require("./src/common/helper");
9+
const errors = require("./src/common/errors");
10+
const routes = require("./src/routes");
11+
const authenticator = require("tc-core-library-js").middleware.jwtAuthenticator;
1412

1513
/**
1614
* Configure all routes for express app
1715
* @param app the express app
1816
*/
1917
module.exports = (app) => {
2018
// Load all routes
19+
_.each(routes, (verbs, path) => {
20+
_.each(verbs, (def, verb) => {
21+
const controllerPath = `./src/controllers/${def.controller}`;
22+
const method = require(controllerPath)[def.method]; // eslint-disable-line
23+
if (!method) {
24+
throw new Error(`${def.method} is undefined`);
25+
}
2126

22-
const ns = AWSXRay.getNamespace()
23-
24-
ns.run(() => {
25-
const rootSegment = new AWSXRay.Segment('v5-challenge-api-custom-segment')
26-
AWSXRay.setSegment(rootSegment)
27+
const actions = [];
28+
actions.push((req, res, next) => {
29+
req.signature = `${def.controller}#${def.method}`;
30+
next();
31+
});
2732

28-
_.each(routes, (verbs, path) => {
29-
_.each(verbs, (def, verb) => {
30-
const controllerPath = `./src/controllers/${def.controller}`
31-
const method = require(controllerPath)[def.method]; // eslint-disable-line
32-
if (!method) {
33-
throw new Error(`${def.method} is undefined`)
33+
actions.push((req, res, next) => {
34+
if (_.get(req, "query.token")) {
35+
_.set(req, "headers.authorization", `Bearer ${_.trim(req.query.token)}`);
3436
}
35-
36-
const actions = []
37+
next();
38+
});
39+
40+
if (def.auth) {
41+
// add Authenticator/Authorization check if route has auth
3742
actions.push((req, res, next) => {
38-
req.signature = `${def.controller}#${def.method}`
39-
next()
40-
})
41-
43+
authenticator(_.pick(config, ["AUTH_SECRET", "VALID_ISSUERS"]))(req, res, next);
44+
});
45+
4246
actions.push((req, res, next) => {
43-
if (_.get(req, 'query.token')) {
44-
_.set(req, 'headers.authorization', `Bearer ${_.trim(req.query.token)}`)
45-
}
46-
next()
47-
})
48-
49-
if (def.auth) {
50-
// add Authenticator/Authorization check if route has auth
51-
actions.push((req, res, next) => {
52-
authenticator(_.pick(config, ['AUTH_SECRET', 'VALID_ISSUERS']))(req, res, next)
53-
})
54-
55-
actions.push((req, res, next) => {
56-
if (req.authUser.isMachine) {
57-
// M2M
58-
if (!req.authUser.scopes || !helper.checkIfExists(def.scopes, req.authUser.scopes)) {
59-
next(new errors.ForbiddenError('You are not allowed to perform this action!'))
60-
} else {
61-
req.authUser.handle = config.M2M_AUDIT_HANDLE
62-
req.userToken = req.headers.authorization.split(' ')[1]
63-
next()
64-
}
47+
if (req.authUser.isMachine) {
48+
// M2M
49+
if (!req.authUser.scopes || !helper.checkIfExists(def.scopes, req.authUser.scopes)) {
50+
next(new errors.ForbiddenError("You are not allowed to perform this action!"));
6551
} else {
66-
req.authUser.userId = String(req.authUser.userId)
67-
// User roles authorization
68-
if (req.authUser.roles) {
69-
if (def.access && !helper.checkIfExists(_.map(def.access, a => a.toLowerCase()), _.map(req.authUser.roles, r => r.toLowerCase()))) {
70-
next(new errors.ForbiddenError('You are not allowed to perform this action!'))
71-
} else {
72-
// user token is used in create/update challenge to ensure user can create/update challenge under specific project
73-
req.userToken = req.headers.authorization.split(' ')[1]
74-
next()
75-
}
76-
} else {
77-
next(new errors.ForbiddenError('You are not authorized to perform this action'))
78-
}
52+
req.authUser.handle = config.M2M_AUDIT_HANDLE;
53+
req.userToken = req.headers.authorization.split(" ")[1];
54+
next();
7955
}
80-
})
81-
} else {
82-
// public API, but still try to authenticate token if provided, but allow missing/invalid token
83-
actions.push((req, res, next) => {
84-
const interceptRes = {}
85-
interceptRes.status = () => interceptRes
86-
interceptRes.json = () => interceptRes
87-
interceptRes.send = () => next()
88-
authenticator(_.pick(config, ['AUTH_SECRET', 'VALID_ISSUERS']))(req, interceptRes, next)
89-
})
90-
91-
actions.push((req, res, next) => {
92-
if (!req.authUser) {
93-
next()
94-
} else if (req.authUser.isMachine) {
95-
if (!def.scopes || !req.authUser.scopes || !helper.checkIfExists(def.scopes, req.authUser.scopes)) {
96-
req.authUser = undefined
56+
} else {
57+
req.authUser.userId = String(req.authUser.userId);
58+
// User roles authorization
59+
if (req.authUser.roles) {
60+
if (
61+
def.access &&
62+
!helper.checkIfExists(
63+
_.map(def.access, (a) => a.toLowerCase()),
64+
_.map(req.authUser.roles, (r) => r.toLowerCase())
65+
)
66+
) {
67+
next(new errors.ForbiddenError("You are not allowed to perform this action!"));
68+
} else {
69+
// user token is used in create/update challenge to ensure user can create/update challenge under specific project
70+
req.userToken = req.headers.authorization.split(" ")[1];
71+
next();
9772
}
98-
next()
9973
} else {
100-
req.authUser.userId = String(req.authUser.userId)
101-
next()
74+
next(new errors.ForbiddenError("You are not authorized to perform this action"));
10275
}
103-
})
104-
}
105-
106-
actions.push(method)
107-
app[verb](`/${config.API_VERSION}${path}`, helper.autoWrapExpress(actions))
108-
})
109-
})
110-
111-
// Check if the route is not found or HTTP method is not supported
112-
app.use('*', (req, res) => {
113-
if (routes[req.baseUrl]) {
114-
res.status(HttpStatus.METHOD_NOT_ALLOWED).json({
115-
message: 'The requested HTTP method is not supported.'
116-
})
76+
}
77+
});
11778
} else {
118-
res.status(HttpStatus.NOT_FOUND).json({
119-
message: 'The requested resource cannot be found.'
120-
})
79+
// public API, but still try to authenticate token if provided, but allow missing/invalid token
80+
actions.push((req, res, next) => {
81+
const interceptRes = {};
82+
interceptRes.status = () => interceptRes;
83+
interceptRes.json = () => interceptRes;
84+
interceptRes.send = () => next();
85+
authenticator(_.pick(config, ["AUTH_SECRET", "VALID_ISSUERS"]))(req, interceptRes, next);
86+
});
87+
88+
actions.push((req, res, next) => {
89+
if (!req.authUser) {
90+
next();
91+
} else if (req.authUser.isMachine) {
92+
if (
93+
!def.scopes ||
94+
!req.authUser.scopes ||
95+
!helper.checkIfExists(def.scopes, req.authUser.scopes)
96+
) {
97+
req.authUser = undefined;
98+
}
99+
next();
100+
} else {
101+
req.authUser.userId = String(req.authUser.userId);
102+
next();
103+
}
104+
});
121105
}
122-
})
123106

124-
rootSegment.close()
125-
})
126-
}
107+
actions.push(method);
108+
app[verb](`/${config.API_VERSION}${path}`, helper.autoWrapExpress(actions));
109+
});
110+
});
111+
112+
// Check if the route is not found or HTTP method is not supported
113+
app.use("*", (req, res) => {
114+
if (routes[req.baseUrl]) {
115+
res.status(HttpStatus.METHOD_NOT_ALLOWED).json({
116+
message: "The requested HTTP method is not supported.",
117+
});
118+
} else {
119+
res.status(HttpStatus.NOT_FOUND).json({
120+
message: "The requested resource cannot be found.",
121+
});
122+
}
123+
});
124+
};

0 commit comments

Comments
 (0)