diff --git a/api-server/src/server/boot/certificate.js b/api-server/src/server/boot/certificate.js index 34a3f1549a..48e5bac58c 100644 --- a/api-server/src/server/boot/certificate.js +++ b/api-server/src/server/boot/certificate.js @@ -9,7 +9,20 @@ import { reportError } from '../middlewares/sentry-error-handler.js'; import { ifNoUser401 } from '../utils/middleware'; import { observeQuery } from '../utils/rx'; + +import { getChallenges } from '../utils/get-curriculum'; + import { + completionHours, + certTypes, + superBlockCertTypeMap, + certTypeTitleMap, + certTypeIdMap, + certIds, + oldDataVizId +} from '../../../../config/certification-settings'; + +const { legacyFrontEndChallengeId, legacyBackEndChallengeId, legacyDataVisId, @@ -25,11 +38,7 @@ import { sciCompPyV7Id, dataAnalysisPyV7Id, machineLearningPyV7Id -} from '../utils/constantStrings.json'; -import { oldDataVizId } from '../../../../config/misc'; -import certTypes from '../utils/certTypes.json'; -import superBlockCertTypeMap from '../utils/superBlockCertTypeMap'; -import { getChallenges } from '../utils/get-curriculum'; +} = certIds; const log = debug('fcc:certification'); @@ -48,7 +57,7 @@ export default function bootCertificate(app) { } export function getFallbackFrontEndDate(completedChallenges, completedDate) { - var chalIds = [...Object.values(certIds), oldDataVizId]; + var chalIds = [...Object.values(certTypeIdMap), oldDataVizId]; const latestCertDate = completedChallenges .filter(chal => chalIds.includes(chal.id)) @@ -110,60 +119,6 @@ function canClaim(ids, completedChallenges = []) { ); } -const certIds = { - [certTypes.frontEnd]: legacyFrontEndChallengeId, - [certTypes.backEnd]: legacyBackEndChallengeId, - [certTypes.dataVis]: legacyDataVisId, - [certTypes.infosecQa]: legacyInfosecQaId, - [certTypes.fullStack]: legacyFullStackId, - [certTypes.respWebDesign]: respWebDesignId, - [certTypes.frontEndLibs]: frontEndLibsId, - [certTypes.jsAlgoDataStruct]: jsAlgoDataStructId, - [certTypes.dataVis2018]: dataVis2018Id, - [certTypes.apisMicroservices]: apisMicroservicesId, - [certTypes.qaV7]: qaV7Id, - [certTypes.infosecV7]: infosecV7Id, - [certTypes.sciCompPyV7]: sciCompPyV7Id, - [certTypes.dataAnalysisPyV7]: dataAnalysisPyV7Id, - [certTypes.machineLearningPyV7]: machineLearningPyV7Id -}; - -const certText = { - [certTypes.frontEnd]: 'Legacy Front End', - [certTypes.backEnd]: 'Legacy Back End', - [certTypes.dataVis]: 'Legacy Data Visualization', - [certTypes.infosecQa]: 'Legacy Information Security and Quality Assurance', - [certTypes.fullStack]: 'Legacy Full Stack', - [certTypes.respWebDesign]: 'Responsive Web Design', - [certTypes.frontEndLibs]: 'Front End Libraries', - [certTypes.jsAlgoDataStruct]: 'JavaScript Algorithms and Data Structures', - [certTypes.dataVis2018]: 'Data Visualization', - [certTypes.apisMicroservices]: 'APIs and Microservices', - [certTypes.qaV7]: 'Quality Assurance', - [certTypes.infosecV7]: 'Information Security', - [certTypes.sciCompPyV7]: 'Scientific Computing with Python', - [certTypes.dataAnalysisPyV7]: 'Data Analysis with Python', - [certTypes.machineLearningPyV7]: 'Machine Learning with Python' -}; - -const completionHours = { - [certTypes.frontEnd]: 400, - [certTypes.backEnd]: 400, - [certTypes.dataVis]: 400, - [certTypes.infosecQa]: 300, - [certTypes.fullStack]: 1800, - [certTypes.respWebDesign]: 300, - [certTypes.frontEndLibs]: 300, - [certTypes.jsAlgoDataStruct]: 300, - [certTypes.dataVis2018]: 300, - [certTypes.apisMicroservices]: 300, - [certTypes.qaV7]: 300, - [certTypes.infosecV7]: 300, - [certTypes.sciCompPyV7]: 300, - [certTypes.dataAnalysisPyV7]: 300, - [certTypes.machineLearningPyV7]: 300 -}; - function getCertById(anId, allChallenges) { return allChallenges .filter(({ id }) => id === anId) @@ -276,7 +231,7 @@ function createVerifyCert(certTypeIds, app) { log(certType); return Observable.of(certTypeIds[certType]) .flatMap(challenge => { - const certName = certText[certType]; + const certName = certTypeTitleMap[certType]; if (user[certType]) { return Observable.just({ type: 'info', @@ -383,8 +338,8 @@ function createShowCert(app) { let { username, cert } = req.params; username = username.toLowerCase(); const certType = superBlockCertTypeMap[cert]; - const certId = certIds[certType]; - const certTitle = certText[certType]; + const certId = certTypeIdMap[certType]; + const certTitle = certTypeTitleMap[certType]; const completionTime = completionHours[certType] || 300; return findUserByUsername$(username, { isCheater: true, @@ -532,7 +487,7 @@ function createShowCert(app) { { type: 'info', message: 'flash.user-not-certified', - variables: { username: username, cert: certText[certType] } + variables: { username: username, cert: certTypeTitleMap[certType] } } ] }); diff --git a/api-server/src/server/boot/randomAPIs.js b/api-server/src/server/boot/randomAPIs.js index 2accf545fc..13bbbbe71c 100644 --- a/api-server/src/server/boot/randomAPIs.js +++ b/api-server/src/server/boot/randomAPIs.js @@ -1,6 +1,6 @@ import request from 'request'; -import constantStrings from '../utils/constantStrings.json'; +import { gitHubUserAgent } from '../../../../config/misc'; import { getRedirectParams } from '../utils/redirection'; const githubClient = process.env.GITHUB_ID; @@ -155,7 +155,7 @@ module.exports = function(app) { function githubCalls(req, res, next) { var githubHeaders = { headers: { - 'User-Agent': constantStrings.gitHubUserAgent + 'User-Agent': gitHubUserAgent }, port: 80 }; diff --git a/api-server/src/server/utils/constantStrings.json b/api-server/src/server/utils/constantStrings.json deleted file mode 100644 index 0da80668f2..0000000000 --- a/api-server/src/server/utils/constantStrings.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "gitHubUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1521.3 Safari/537.36", - - "legacyFrontEndChallengeId": "561add10cb82ac38a17513be", - "legacyBackEndChallengeId": "660add10cb82ac38a17513be", - "legacyDataVisId": "561add10cb82ac39a17513bc", - "legacyInfosecQaId": "561add10cb82ac38a17213bc", - "legacyFullStackId": "561add10cb82ac38a17213bd", - - "respWebDesignId": "561add10cb82ac38a17513bc", - "frontEndLibsId": "561acd10cb82ac38a17513bc", - "dataVis2018Id": "5a553ca864b52e1d8bceea14", - "jsAlgoDataStructId": "561abd10cb81ac38a17513bc", - "apisMicroservicesId": "561add10cb82ac38a17523bc", - "qaV7Id": "5e611829481575a52dc59c0e", - "infosecV7Id": "5e6021435ac9d0ecd8b94b00", - "sciCompPyV7Id": "5e44431b903586ffb414c951", - "dataAnalysisPyV7Id": "5e46fc95ac417301a38fb934", - "machineLearningPyV7Id": "5e46fc95ac417301a38fb935" -} diff --git a/api-server/src/server/utils/superBlockCertTypeMap.js b/api-server/src/server/utils/superBlockCertTypeMap.js deleted file mode 100644 index b2c4ec8907..0000000000 --- a/api-server/src/server/utils/superBlockCertTypeMap.js +++ /dev/null @@ -1,26 +0,0 @@ -import certTypes from './certTypes.json'; - -const superBlockCertTypeMap = { - // legacy - 'legacy-front-end': certTypes.frontEnd, - 'legacy-back-end': certTypes.backEnd, - 'legacy-data-visualization': certTypes.dataVis, - // Keep these slugs the same so we don't - // break existing links - 'information-security-and-quality-assurance': certTypes.infosecQa, - 'full-stack': certTypes.fullStack, - - // modern - 'responsive-web-design': certTypes.respWebDesign, - 'javascript-algorithms-and-data-structures': certTypes.jsAlgoDataStruct, - 'front-end-libraries': certTypes.frontEndLibs, - 'data-visualization': certTypes.dataVis2018, - 'apis-and-microservices': certTypes.apisMicroservices, - 'quality-assurance-v7': certTypes.qaV7, - 'information-security-v7': certTypes.infosecV7, - 'scientific-computing-with-python-v7': certTypes.sciCompPyV7, - 'data-analysis-with-python-v7': certTypes.dataAnalysisPyV7, - 'machine-learning-with-python-v7': certTypes.machineLearningPyV7 -}; - -export default superBlockCertTypeMap; diff --git a/config/certification-settings.js b/config/certification-settings.js new file mode 100644 index 0000000000..4998a91e12 --- /dev/null +++ b/config/certification-settings.js @@ -0,0 +1,120 @@ +const certTypes = { + frontEnd: 'isFrontEndCert', + backEnd: 'isBackEndCert', + dataVis: 'isDataVisCert', + respWebDesign: 'isRespWebDesignCert', + frontEndLibs: 'isFrontEndLibsCert', + dataVis2018: 'is2018DataVisCert', + jsAlgoDataStruct: 'isJsAlgoDataStructCert', + apisMicroservices: 'isApisMicroservicesCert', + infosecQa: 'isInfosecQaCert', + qaV7: 'isQaCertV7', + infosecV7: 'isInfosecCertV7', + sciCompPyV7: 'isSciCompPyCertV7', + dataAnalysisPyV7: 'isDataAnalysisPyCertV7', + machineLearningPyV7: 'isMachineLearningPyCertV7', + fullStack: 'isFullStackCert' +}; + +const certIds = { + legacyFrontEndChallengeId: '561add10cb82ac38a17513be', + legacyBackEndChallengeId: '660add10cb82ac38a17513be', + legacyDataVisId: '561add10cb82ac39a17513bc', + legacyInfosecQaId: '561add10cb82ac38a17213bc', + legacyFullStackId: '561add10cb82ac38a17213bd', + respWebDesignId: '561add10cb82ac38a17513bc', + frontEndLibsId: '561acd10cb82ac38a17513bc', + dataVis2018Id: '5a553ca864b52e1d8bceea14', + jsAlgoDataStructId: '561abd10cb81ac38a17513bc', + apisMicroservicesId: '561add10cb82ac38a17523bc', + qaV7Id: '5e611829481575a52dc59c0e', + infosecV7Id: '5e6021435ac9d0ecd8b94b00', + sciCompPyV7Id: '5e44431b903586ffb414c951', + dataAnalysisPyV7Id: '5e46fc95ac417301a38fb934', + machineLearningPyV7Id: '5e46fc95ac417301a38fb935' +}; + +const completionHours = { + [certTypes.frontEnd]: 400, + [certTypes.backEnd]: 400, + [certTypes.dataVis]: 400, + [certTypes.infosecQa]: 300, + [certTypes.fullStack]: 1800, + [certTypes.respWebDesign]: 300, + [certTypes.frontEndLibs]: 300, + [certTypes.jsAlgoDataStruct]: 300, + [certTypes.dataVis2018]: 300, + [certTypes.apisMicroservices]: 300, + [certTypes.qaV7]: 300, + [certTypes.infosecV7]: 300, + [certTypes.sciCompPyV7]: 300, + [certTypes.dataAnalysisPyV7]: 300, + [certTypes.machineLearningPyV7]: 300 +}; + +const superBlockCertTypeMap = { + // legacy + 'legacy-front-end': certTypes.frontEnd, + 'legacy-back-end': certTypes.backEnd, + 'legacy-data-visualization': certTypes.dataVis, + // Keep these slugs the same so we don't + // break existing links + 'information-security-and-quality-assurance': certTypes.infosecQa, + 'full-stack': certTypes.fullStack, + + // modern + 'responsive-web-design': certTypes.respWebDesign, + 'javascript-algorithms-and-data-structures': certTypes.jsAlgoDataStruct, + 'front-end-libraries': certTypes.frontEndLibs, + 'data-visualization': certTypes.dataVis2018, + 'apis-and-microservices': certTypes.apisMicroservices, + 'quality-assurance-v7': certTypes.qaV7, + 'information-security-v7': certTypes.infosecV7, + 'scientific-computing-with-python-v7': certTypes.sciCompPyV7, + 'data-analysis-with-python-v7': certTypes.dataAnalysisPyV7, + 'machine-learning-with-python-v7': certTypes.machineLearningPyV7 +}; + +const certTypeIdMap = { + [certTypes.frontEnd]: certIds.legacyFrontEndChallengeId, + [certTypes.backEnd]: certIds.legacyBackEndChallengeId, + [certTypes.dataVis]: certIds.legacyDataVisId, + [certTypes.infosecQa]: certIds.legacyInfosecQaId, + [certTypes.fullStack]: certIds.legacyFullStackId, + [certTypes.respWebDesign]: certIds.respWebDesignId, + [certTypes.frontEndLibs]: certIds.frontEndLibsId, + [certTypes.jsAlgoDataStruct]: certIds.jsAlgoDataStructId, + [certTypes.dataVis2018]: certIds.dataVis2018Id, + [certTypes.apisMicroservices]: certIds.apisMicroservicesId, + [certTypes.qaV7]: certIds.qaV7Id, + [certTypes.infosecV7]: certIds.infosecV7Id, + [certTypes.sciCompPyV7]: certIds.sciCompPyV7Id, + [certTypes.dataAnalysisPyV7]: certIds.dataAnalysisPyV7Id, + [certTypes.machineLearningPyV7]: certIds.machineLearningPyV7Id +}; + +const certTypeTitleMap = { + [certTypes.frontEnd]: 'Legacy Front End', + [certTypes.backEnd]: 'Legacy Back End', + [certTypes.dataVis]: 'Legacy Data Visualization', + [certTypes.infosecQa]: 'Legacy Information Security and Quality Assurance', + [certTypes.fullStack]: 'Legacy Full Stack', + [certTypes.respWebDesign]: 'Responsive Web Design', + [certTypes.frontEndLibs]: 'Front End Libraries', + [certTypes.jsAlgoDataStruct]: 'JavaScript Algorithms and Data Structures', + [certTypes.dataVis2018]: 'Data Visualization', + [certTypes.apisMicroservices]: 'APIs and Microservices', + [certTypes.qaV7]: 'Quality Assurance', + [certTypes.infosecV7]: 'Information Security', + [certTypes.sciCompPyV7]: 'Scientific Computing with Python', + [certTypes.dataAnalysisPyV7]: 'Data Analysis with Python', + [certTypes.machineLearningPyV7]: 'Machine Learning with Python' +}; + +exports.oldDataVizId = '561add10cb82ac38a17513b3'; +exports.completionHours = completionHours; +exports.certTypes = certTypes; +exports.superBlockCertTypeMap = superBlockCertTypeMap; +exports.certIds = certIds; +exports.certTypeIdMap = certTypeIdMap; +exports.certTypeTitleMap = certTypeTitleMap; diff --git a/config/misc.js b/config/misc.js index a1cf55a651..ec12ccb2b7 100644 --- a/config/misc.js +++ b/config/misc.js @@ -1,2 +1,3 @@ -exports.oldDataVizId = '561add10cb82ac38a17513b3'; exports.defaultUserImage = 'https://freecodecamp.com/sample-image.png'; +exports.gitHubUserAgent = + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1521.3 Safari/537.36';