Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/formHelpers/form-validators.tsx (TypeScript)

Code before:
const localhostRegex = /localhost:/;
const httpRegex = /http(?!s|([^s]+?localhost))/;

function isPathRoot(urlString: string): boolean {
  try {
    return new URL(urlString).pathname !== '/';
  } catch {
    return false;
  }
}

type Validator = (value: string) => React.ReactElement | null;

// example link: https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8
export const isMicrosoftLearnLink = (value: string): boolean => {
  let url;
  try {
    url = new URL(value);
  } catch {
    return false;
  }

  const correctDomain = url.hostname === 'learn.microsoft.com';
  const correctPath = !!url.pathname.match(
    /^\/[^/]+\/training\/achievements\//
  );
  const hasSharingId = !!url.searchParams.get('sharingId');
  const hasUsername = !!url.searchParams.get('username');
  return correctDomain && correctPath && hasSharingId && hasUsername;
};

export const microsoftValidator: Validator = value =>
  !isMicrosoftLearnLink(value) ? <Trans>validation.ms-learn-link</Trans> : null;

export const editorValidator: Validator = value =>
  editorRegex.test(value) ? <Trans>validation.editor-url</Trans> : null;

export const fCCValidator: Validator = value =>
  fCCRegex.test(value) ? <Trans>validation.own-work-url</Trans> : null;

export const localhostValidator: Validator = value =>
  localhostRegex.test(value) ? (
    <Trans>validation.publicly-visible-url</Trans>
  ) : null;

export const httpValidator: Validator = value =>
  httpRegex.test(value) ? <Trans>validation.http-url</Trans> : null;

export const pathValidator: Validator = value =>
  isPathRoot(value) ? <Trans>validation.path-url</Trans> : null;


Review comment (security):
```suggestion
  const correctPath = !!url.pathname.match(
    /^\/[^\/]+\/training\/achievements\//
  );
```

There's an error in this regex. It does seem to work when you escape that. Maybe I didn't explain it enough, but the URL's are specific to the challenge. The URL for the first trophy challenge looks like this:

`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8`

The URL for the second trophy challenge looks like this:

`https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-2.trophy?username=moT01&sharingId=E2EF453C1F9208B8`

^ the only difference is the `part-#`. The same goes for the rest of the trophy challenges through `part-6` (all of them). It would be nice to validate that the `part-#` is correct for the specific challenge campers are trying to submit. I don't think it's entirely necessary for the MVP - here's a suggestion that's a little more specific though...

```suggestion
  const correctPath = !!url.pathname.match(
    /^\/[^\/]+\/training\/achievements\/learn\.wwl\.get-started-c-sharp-part-\d\.trophy$/
  );
```

Code after:
const localhostRegex = /localhost:/;
const httpRegex = /http(?!s|([^s]+?localhost))/;

function isPathRoot(urlString: string): boolean {
  try {
    return new URL(urlString).pathname !== '/';
  } catch {
    return false;
  }
}

type Validator = (value: string) => React.ReactElement | null;

// example link: https://learn.microsoft.com/en-us/training/achievements/learn.wwl.get-started-c-sharp-part-1.trophy?username=moT01&sharingId=E2EF453C1F9208B8
export const isMicrosoftLearnLink = (value: string): boolean => {
  let url;
  try {
    url = new URL(value);
  } catch {
    return false;
  }

  const correctDomain = url.hostname === 'learn.microsoft.com';
  const correctPath = !!url.pathname.match(
    /^\/[^/]+\/training\/achievements\/learn\.wwl\.get-started-c-sharp-part-\d\.trophy$/
  );
  const hasSharingId = !!url.searchParams.get('sharingId');
  const hasUsername = !!url.searchParams.get('username');
  return correctDomain && correctPath && hasSharingId && hasUsername;
};

export const microsoftValidator: Validator = value =>
  !isMicrosoftLearnLink(value) ? <Trans>validation.ms-learn-link</Trans> : null;

export const editorValidator: Validator = value =>
  editorRegex.test(value) ? <Trans>validation.editor-url</Trans> : null;

export const fCCValidator: Validator = value =>
  fCCRegex.test(value) ? <Trans>validation.own-work-url</Trans> : null;

export const localhostValidator: Validator = value =>
  localhostRegex.test(value) ? (
    <Trans>validation.publicly-visible-url</Trans>
  ) : null;

export const httpValidator: Validator = value =>
  httpRegex.test(value) ? <Trans>validation.http-url</Trans> : null;

export const pathValidator: Validator = value =>
  isPathRoot(value) ? <Trans>validation.path-url</Trans> : null;