fix: handle uppercase and missing user verification (#44444)

* fix: hotfix for isHonest null

* fix: early return if no user?

* fix: handle invalid input on api

Also lowerCases the username it receives since the client could send any
case.

* fix: report errors to user when verification fails

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Nicholas Carrigan (he/him)
2021-12-10 03:23:26 -08:00
committed by GitHub
parent fd0a140c8a
commit 42acc542b7
4 changed files with 43 additions and 9 deletions

View File

@ -55,7 +55,7 @@ function destroyAll(id, Model) {
return Observable.fromNodeCallback(Model.destroyAll, Model)({ userId: id }); return Observable.fromNodeCallback(Model.destroyAll, Model)({ userId: id });
} }
function ensureLowerCaseString(maybeString) { export function ensureLowerCaseString(maybeString) {
return (maybeString && maybeString.toLowerCase()) || ''; return (maybeString && maybeString.toLowerCase()) || '';
} }

View File

@ -20,6 +20,7 @@ import { reportError } from '../middlewares/sentry-error-handler.js';
import { getChallenges } from '../utils/get-curriculum'; import { getChallenges } from '../utils/get-curriculum';
import { ifNoUser401 } from '../utils/middleware'; import { ifNoUser401 } from '../utils/middleware';
import { observeQuery } from '../utils/rx'; import { observeQuery } from '../utils/rx';
import { ensureLowerCaseString } from '../../common/models/user';
const { const {
legacyFrontEndChallengeId, legacyFrontEndChallengeId,
@ -523,7 +524,7 @@ function createVerifyCanClaim(certTypeIds, app) {
let certType = superBlockCertTypeMap[superBlock]; let certType = superBlockCertTypeMap[superBlock];
log(certType); log(certType);
return findUserByUsername$(username, { return findUserByUsername$(ensureLowerCaseString(username), {
isFrontEndCert: true, isFrontEndCert: true,
isBackEndCert: true, isBackEndCert: true,
isFullStackCert: true, isFullStackCert: true,
@ -544,15 +545,36 @@ function createVerifyCanClaim(certTypeIds, app) {
isHonest: true, isHonest: true,
completedChallenges: true completedChallenges: true
}).subscribe(user => { }).subscribe(user => {
if (!user) {
return res.status(404).json({
message: {
type: 'info',
message: 'flash.username-not-found',
variables: { username }
}
});
}
if (!certTypeIds[certType]) {
return res.status(404).json({
message: {
type: 'info',
// TODO: create a specific 'flash.cert-not-found' message
message: 'flash.could-not-find'
}
});
}
return Observable.of(certTypeIds[certType]) return Observable.of(certTypeIds[certType])
.flatMap(challenge => { .flatMap(challenge => {
const certName = certTypeTitleMap[certType]; const certName = certTypeTitleMap[certType];
const { tests = [] } = challenge; const { tests = [] } = challenge;
const { isHonest, completedChallenges } = user;
const isProjectsCompleted = canClaim(tests, completedChallenges);
let result = 'incomplete-requirements'; let result = 'incomplete-requirements';
let status = false; let status = false;
const { isHonest, completedChallenges } = user;
const isProjectsCompleted = canClaim(tests, completedChallenges);
if (isHonest && isProjectsCompleted) { if (isHonest && isProjectsCompleted) {
status = true; status = true;
result = 'requirements-met'; result = 'requirements-met';

View File

@ -91,12 +91,22 @@ const CertChallenge = ({
void (async () => { void (async () => {
try { try {
const data = await getVerifyCanClaimCert(username, superBlock); const data = await getVerifyCanClaimCert(username, superBlock);
const { status, result } = data?.response?.message; if (data?.message) {
setCanClaimCert(status); setCanClaimCert(false);
setCertVerificationMessage(result); createFlashMessage(data.message);
setVerificationComplete(true); } else {
const { status, result } = data?.response?.message;
setCanClaimCert(status);
setCertVerificationMessage(result);
}
} catch (e) { } catch (e) {
// TODO: How do we handle errors...? console.error(e);
createFlashMessage({
type: 'danger',
message: FlashMessages.ReallyWeird
});
} finally {
setVerificationComplete(true);
} }
})(); })();
} }

View File

@ -1,5 +1,6 @@
import cookies from 'browser-cookies'; import cookies from 'browser-cookies';
import envData from '../../../config/env.json'; import envData from '../../../config/env.json';
import { FlashMessageArg } from '../components/Flash/redux';
import type { import type {
ChallengeFile, ChallengeFile,
@ -172,6 +173,7 @@ export interface GetVerifyCanClaimCert {
}; };
isCertMap: ClaimedCertifications; isCertMap: ClaimedCertifications;
completedChallenges: CompletedChallenge[]; completedChallenges: CompletedChallenge[];
message?: FlashMessageArg;
} }
export function getVerifyCanClaimCert( export function getVerifyCanClaimCert(