18F/identity-idp

View on GitHub
app/javascript/packs/mock-device-profiling.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import { render } from 'react-dom';
import { useInstanceId } from '@18f/identity-react-hooks';
import { ChangeEvent, useState, useEffect } from 'react';

const { currentScript } = document;

function loadSessionId(): string | undefined {
  if (currentScript instanceof HTMLScriptElement) {
    return new URL(currentScript.src).searchParams.get('session_id') || undefined;
  }
}

function submitMockFraudResult({ result, sessionId }: { result: string; sessionId?: string }) {
  fetch('/test/device_profiling', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      session_id: sessionId,
      result,
    }),
  });
}

interface ChaosOption {
  apply: () => void;
  undo: () => void;
}

const CHAOS_OPTIONS: ChaosOption[] = [
  {
    apply: () => {
      document.body.style.transform = 'scale(-1, 1)';
    },
    undo: () => {
      document.body.style.transform = '';
    },
  },
  {
    apply: () => {
      document.body.style.transform = 'rotate(5deg)';
    },
    undo: () => {
      document.body.style.transform = '';
    },
  },
  {
    apply: () => {
      document.body.style.filter = 'invert(100%)';
    },
    undo: () => {
      document.body.style.filter = '';
    },
  },
  {
    apply: () => {
      document.body.style.fontFamily = 'Comic Sans MS';
    },
    undo: () => {
      document.body.style.fontFamily = '';
    },
  },
];

function MockDeviceProfilingOptions() {
  const [selectedValue, setSelectedValue] = useState('pass');

  useEffect(() => {
    if (selectedValue === 'chaotic') {
      const randomChaosOption = CHAOS_OPTIONS[Math.floor(Math.random() * CHAOS_OPTIONS.length)];
      randomChaosOption.apply();
      return randomChaosOption.undo;
    }
    if (selectedValue) {
      submitMockFraudResult({ result: selectedValue, sessionId: loadSessionId() });
    }
  }, [selectedValue]);

  const instanceId = useInstanceId();
  const inputId = `select-input-${instanceId}`;

  const options = [
    { value: 'pass', title: 'Pass' },
    { value: 'reject', title: 'Reject' },
    { value: 'review', title: 'Review' },
    { value: 'no_result', title: 'No Result' },
    { value: 'chaotic', title: 'Do something chaotic' },
  ];

  return (
    <>
      {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
      <label className="usa-label" htmlFor={inputId}>
        <strong className="text-accent-warm-dark">For sandbox testing only:</strong> Mock device
        profiling behavior
      </label>
      <select
        className="border-05 border-accent-warm-dark"
        onChange={(event: ChangeEvent<HTMLSelectElement>) => {
          const targetValue = event.target.value;
          setSelectedValue(targetValue);
        }}
        name="mock_profiling_result"
        id={inputId}
        defaultValue={selectedValue}
      >
        {options.map(({ value, title }) => (
          <option value={value} key={value}>
            {title}
          </option>
        ))}
      </select>
    </>
  );
}

document.addEventListener('DOMContentLoaded', () => {
  const ssnInput = document.getElementsByName('doc_auth[ssn]')[0];

  if (ssnInput) {
    const passwordToggle = ssnInput.closest('lg-password-toggle');

    const div = document.createElement('div');
    passwordToggle?.parentElement?.appendChild(div);

    render(<MockDeviceProfilingOptions />, div);
  }
});