Repository: freeCodeCamp/freeCodeCamp
File: api-server/src/server/boot/challenge.js (JavaScript)

Code before:
    body: { id, challengeType, solution, githubLink }
  } = req;

  // ToDO: Validate other things (challengeFiles, etc)
  const isValidChallengeCompletionErrorMsg = {
    type: 'error',
    message: 'That does not appear to be a valid challenge submission.'
  };

  if (!ObjectID.isValid(id)) {
    log('isObjectId', id, ObjectID.isValid(id));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  if ('challengeType' in req.body && !isNumeric(String(challengeType))) {
    log('challengeType', challengeType, isNumeric(challengeType));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  // If `backEndProject`:
  // - `solution` needs to exist, but does not have to be valid URL
  // - `githubLink` needs to exist and be valid URL
  if (challengeType === challengeTypes.backEndProject) {
    if (!solution || !githubLink) {
      log('isObjectId', id, ObjectID.isValid(id));
      return res.status(403).json(isValidChallengeCompletionErrorMsg);
    } else if (!isURL(githubLink)) {
      log('isObjectId', id, ObjectID.isValid(id));
      return res.status(403).json(isValidChallengeCompletionErrorMsg);
    }
  } else if ('solution' in req.body && !isURL(solution)) {
    log('isObjectId', id, ObjectID.isValid(id));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  return next();
}

export async function modernChallengeCompleted(req, res, next) {
  const user = req.user;

  try {
    // This is an ugly way to update `user.completedChallenges`
    await user.getCompletedChallenges$().toPromise();
  } catch (e) {
    return next(e);
  }

  const completedDate = Date.now();
  const { id, files, challengeType } = req.body;

  const completedChallenge = {
    id,
    files,

Review comment (suggestion):
The comment above this says, `` `solution` needs to exist, but does not have to be valid URL`` - this appears to check that it is valid. Just want to make sure that's intended. I think it's fine.

Code after:
    body: { id, challengeType, solution, githubLink }
  } = req;

  // ToDO: Validate other things (challengeFiles, etc)
  const isValidChallengeCompletionErrorMsg = {
    type: 'error',
    message: 'That does not appear to be a valid challenge submission.'
  };

  if (!ObjectID.isValid(id)) {
    log('isObjectId', id, ObjectID.isValid(id));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  if ('challengeType' in req.body && !isNumeric(String(challengeType))) {
    log('challengeType', challengeType, isNumeric(challengeType));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  // If `backEndProject`:
  // - `solution` needs to exist, but does not have to be valid URL
  // - `githubLink` needs to exist and be valid URL
  if (challengeType === challengeTypes.backEndProject) {
    if (!solution || !isURL(githubLink + '')) {
      log('isObjectId', id, ObjectID.isValid(id));
      return res.status(403).json(isValidChallengeCompletionErrorMsg);
    }
  } else if ('solution' in req.body && !isURL(solution)) {
    log('isObjectId', id, ObjectID.isValid(id));
    return res.status(403).json(isValidChallengeCompletionErrorMsg);
  }
  return next();
}

export async function modernChallengeCompleted(req, res, next) {
  const user = req.user;

  try {
    // This is an ugly way to update `user.completedChallenges`
    await user.getCompletedChallenges$().toPromise();
  } catch (e) {
    return next(e);
  }

  const completedDate = Date.now();
  const { id, files, challengeType } = req.body;

  const completedChallenge = {
    id,
    files,
    completedDate
  };