Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit ec78ebd

Browse files
author
dengjun
committed
output from task part1
1 parent 431809d commit ec78ebd

File tree

14 files changed

+677
-9
lines changed

14 files changed

+677
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This is a [single-spa](https://single-spa.js.org/) example React microapp.
2525
| `npm run test` | Run unit tests |
2626
| `npm run watch-tests` | Watch for file changes and run unit tests on changes |
2727
| `npm run coverage` | Generate test code coverage report |
28+
| `npm run mock-api` | Start the mock api which mocks Recruit api |
2829

2930
## Local Deployment
3031

config/default.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,43 @@ module.exports = {
1111
BASE: "https://www.topcoder-dev.com",
1212
COMMUNITY_APP: "https://community-app.topcoder-dev.com",
1313
},
14+
RECRUIT_API: process.env.RECRUIT_API || "https://www.topcoder-dev.com",
1415
// the server api base path
1516
API_BASE_PATH: process.env.API_BASE_PATH || "/earn-app/api/my-gigs",
1617
// the log level, default is 'debug'
1718
LOG_LEVEL: process.env.LOG_LEVEL || "debug",
1819
// The authorization secret used during token verification.
19-
AUTH_SECRET: process.env.AUTH_SECRET || "UgL4(SEAM*~yc7L~vWrKKN&GHrwyc9N[@nVxm,X?#b4}7:xbzM",
20+
AUTH_SECRET:
21+
process.env.AUTH_SECRET ||
22+
"UgL4(SEAM*~yc7L~vWrKKN&GHrwyc9N[@nVxm,X?#b4}7:xbzM",
2023
// The valid issuer of tokens, a json array contains valid issuer.
2124
VALID_ISSUERS:
2225
process.env.VALID_ISSUERS ||
2326
'["https://api.topcoder-dev.com", "https://api.topcoder.com", "https://topcoder-dev.auth0.com/", "https://auth.topcoder-dev.com/"]',
2427
// Auth0 URL, used to get TC M2M token
25-
AUTH0_URL: process.env.AUTH0_URL || "https://topcoder-dev.auth0.com/oauth/token",
28+
AUTH0_URL:
29+
process.env.AUTH0_URL || "https://topcoder-dev.auth0.com/oauth/token",
2630
// Auth0 audience, used to get TC M2M token
2731
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || "https://m2m.topcoder-dev.com/",
2832
// Auth0 client id, used to get TC M2M token
29-
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID || "gZ6jt50HYHLBf4vhxjUhXPZOR7Q5lk4k",
33+
AUTH0_CLIENT_ID:
34+
process.env.AUTH0_CLIENT_ID || "gZ6jt50HYHLBf4vhxjUhXPZOR7Q5lk4k",
3035
// Auth0 client secret, used to get TC M2M token
31-
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET || "zb-OV1Rl3QpUkt4BexJ-Rs58jYMazCre1_97aU4PJIvQdVB-DmQIs61W3gCfPyP4",
36+
AUTH0_CLIENT_SECRET:
37+
process.env.AUTH0_CLIENT_SECRET ||
38+
"zb-OV1Rl3QpUkt4BexJ-Rs58jYMazCre1_97aU4PJIvQdVB-DmQIs61W3gCfPyP4",
3239
// Proxy Auth0 URL, used to get TC M2M token
3340
AUTH0_PROXY_SERVER_URL: process.env.AUTH0_PROXY_SERVER_URL,
3441
m2m: {
3542
M2M_AUDIT_USER_ID:
3643
process.env.M2M_AUDIT_USER_ID || "00000000-0000-0000-0000-000000000000",
3744
M2M_AUDIT_HANDLE: process.env.M2M_AUDIT_HANDLE || "TopcoderService",
3845
},
46+
MOCK_API_PORT: process.env.MOCK_API_PORT || 4000,
47+
ALLOWED_FILE_TYPES: process.env.ALLOWED_FILE_TYPES || [
48+
"pdf",
49+
"doc",
50+
"docx",
51+
"txt",
52+
],
3953
};

package-lock.json

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"format": "prettier --write \"./**\"",
1111
"test": "cross-env BABEL_ENV=test jest",
1212
"watch-tests": "cross-env BABEL_ENV=test jest --watch",
13-
"coverage": "cross-env BABEL_ENV=test jest --coverage"
13+
"coverage": "cross-env BABEL_ENV=test jest --coverage",
14+
"mock-api": "node ./src/api/mock-api/mock-api.js"
1415
},
1516
"devDependencies": {
1617
"@babel/core": "^7.7.5",
@@ -61,12 +62,14 @@
6162
"@babel/runtime": "^7.13.10",
6263
"@reach/router": "^1.3.4",
6364
"autoprefixer": "^8.6.5",
65+
"cors": "^2.8.5",
66+
"country-calling-code": "0.0.3",
6467
"dotenv": "^10.0.0",
6568
"express": "^4.17.1",
69+
"express-fileupload": "^1.2.1",
6670
"express-interceptor": "^1.2.0",
6771
"get-parameter-names": "^0.3.0",
6872
"http-status": "^1.5.0",
69-
"country-calling-code": "0.0.3",
7073
"i18n-iso-countries": "^6.7.0",
7174
"joi": "^17.4.0",
7275
"lodash": "^4.17.21",

src/api/app-constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
const Scopes = {
66
// JobApplication
77
READ_JOBAPPLICATION: "read:earn-jobApplications",
8+
READ_PROFILE: "read:earn-profile",
9+
WRITE_PROFILE: "write:earn-profile",
10+
ALL_PROFILE: "all:earn-profile",
811
};
912

1013
module.exports = {

src/api/app-routes.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
const _ = require("lodash");
66
const config = require("config");
7+
const express = require("express");
8+
const cors = require("cors");
9+
const fileUpload = require("express-fileupload");
710
const helper = require("./common/helper");
811
const errors = require("./common/errors");
912
const routes = require("./routes");
@@ -14,6 +17,9 @@ const authenticator = require("tc-core-library-js").middleware.jwtAuthenticator;
1417
* @param app the express app
1518
*/
1619
module.exports = (app) => {
20+
app.use(express.json());
21+
app.use(cors());
22+
app.use(fileUpload());
1723
// intercept the response body from jwtAuthenticator
1824
app.use(helper.interceptor);
1925
// Load all routes

src/api/common/helper.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,93 @@ async function getJobs(criteria) {
314314
};
315315
}
316316

317+
/**
318+
* Get member details
319+
* @param {string} handle the handle of the user
320+
* @param {string} query the query criteria
321+
* @return {Object} the object of member details
322+
*/
323+
async function getMember(handle, query) {
324+
const token = await getM2MToken();
325+
const url = `${config.API.V5}/members/${handle}`;
326+
const res = await request
327+
.get(url)
328+
.query(query)
329+
.set("Authorization", `Bearer ${token}`)
330+
.set("Accept", "application/json");
331+
localLogger.debug({
332+
context: "getMember",
333+
message: `response body: ${JSON.stringify(res.body)}`,
334+
});
335+
return res.body;
336+
}
337+
338+
/**
339+
* Update member details
340+
* @param {string} handle the handle of the user
341+
* @param {object} data the data to be updated
342+
* @return {object} the object of updated member details
343+
*/
344+
async function updateMember(currentUser, data) {
345+
const token = currentUser.jwtToken;
346+
const url = `${config.API.V5}/members/${currentUser.handle}`;
347+
const res = await request
348+
.put(url)
349+
.set("Authorization", token)
350+
.set("Content-Type", "application/json")
351+
.set("Accept", "application/json")
352+
.send(data);
353+
localLogger.debug({
354+
context: "updateMember",
355+
message: `response body: ${JSON.stringify(res.body)}`,
356+
});
357+
return res.body;
358+
}
359+
360+
/**
361+
* Get Recruit CRM profile details
362+
* @param {object} currentUser the user who performs the operation
363+
* @return {object} the object of profile details
364+
*/
365+
async function getRCRMProfile(currentUser) {
366+
const token = currentUser.jwtToken;
367+
const url = `${config.RECRUIT_API}/api/recruit/profile`;
368+
const res = await request
369+
.get(url)
370+
.set("Authorization", token)
371+
.set("Accept", "application/json");
372+
localLogger.debug({
373+
context: "getRCRMProfile",
374+
message: `response body: ${JSON.stringify(res.body)}`,
375+
});
376+
return res.body;
377+
}
378+
379+
/**
380+
* Update Recruit CRM profile details
381+
* @param {object} currentUser the user who performs the operation
382+
* @param {object} file the resume file
383+
* @param {object} data the data to be updated
384+
* @return {object} the returned object
385+
*/
386+
async function updateRCRMProfile(currentUser, file, data) {
387+
const token = currentUser.jwtToken;
388+
const url = `${config.RECRUIT_API}/api/recruit/profile`;
389+
const res = await request
390+
.post(url)
391+
.set("Authorization", token)
392+
.set("Content-Type", "multipart/form-data")
393+
.set("Accept", "application/json")
394+
.field("phone", data.phone)
395+
.field("availability", data.availability)
396+
.attach("resume", file.data, file.name);
397+
localLogger.debug({
398+
context: "updateRCRMProfile",
399+
message: `response body: ${JSON.stringify(res.body)}`,
400+
});
401+
return res.body;
402+
}
403+
317404
module.exports = {
318405
errorHandler,
319406
interceptor,
@@ -324,4 +411,8 @@ module.exports = {
324411
getCurrentUserDetails,
325412
getJobCandidates,
326413
getJobs,
414+
getMember,
415+
updateMember,
416+
getRCRMProfile,
417+
updateRCRMProfile,
327418
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Controller for Profile endpoints
3+
*/
4+
const service = require("../services/ProfileService");
5+
const helper = require("../common/helper");
6+
7+
/**
8+
* Get current user's profile
9+
* @param req the request
10+
* @param res the response
11+
*/
12+
async function getMyProfile(req, res) {
13+
res.send(await service.getMyProfile(req.authUser));
14+
}
15+
16+
/**
17+
* Update current user's profile
18+
* @param req the request
19+
* @param res the response
20+
*/
21+
async function updateMyProfile(req, res) {
22+
await service.updateMyProfile(req.authUser, req.files, req.body);
23+
res.status(204).end();
24+
}
25+
26+
module.exports = {
27+
getMyProfile,
28+
updateMyProfile,
29+
};

src/api/data/resume.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
My resume

0 commit comments

Comments
 (0)