Under UserAPI there are nested classes Security and CRUD.
CRUD is an acronym related to the basic operations done on data within a database
Create: POST requests
Creates new user with input data
Performs error checking
Sets up user object -> adds to user database
Read: GET requests
Handles user retrieval requests
Data -> JSON + response
Update: PUT/PATCH requests
Updates based on user input
Commits changes to user database
This is done with the PUT request
Delete: DELETE requests
Handles user delete requests
Deletes user from database

Validates data through HTTP POST requests
Find user id and checks validity of entered password with that stored
JSON response with authentication status, ex. Login if valid, and no login in invalid
Not necessarily authorization - authentication allows login while authorization allows access to a certain resource

Post request used for the addition of new users
Get request displays are user data table
Put request implemented to update user information
Delete request removes specified users
    // uri variable and options object are obtained from config.js
    import { uri, options } from '/CompSci/assets/js/api/config.js';
    const url = uri + '/api/users/authenticate';
    const body = {
            // name: document.getElementById("name").value,
            uid: "toby",
            password: "123toby"
            // dob: document.getElementById("dob").value
        };
    const authOptions = {
            ...options, // This will copy all properties from options
            method: 'POST', // Override the method property
            cache: 'no-cache', // Set the cache property
            body: JSON.stringify(body)
        };
    fetch(url, authOptions)
    function login_user(){
        // Set Authenticate endpoint
        const url = uri + '/api/users/';
        // Set the body of the request to include login data from the DOM
        const body = {
            name: document.getElementById("name").value,
            uid: document.getElementById("uid").value,
            password: document.getElementById("password").value,
            dob: document.getElementById("dob").value
        };
        // Change options according to Authentication requirements
        const authOptions = {
            ...options, // This will copy all properties from options
            method: 'POST', // Override the method property
            cache: 'no-cache', // Set the cache property
            body: JSON.stringify(body)
        };
        // Fetch JWT
        fetch(url, authOptions)
        .then(response => {
            // handle error response from Web API
            if (!response.ok) {
                const errorMsg = 'Login error: ' + response.status;
                console.log(errorMsg);
                return;
            }
            // Success!!!
            // Redirect to the database page
            window.location.href = "/CompSci/data/database";
        })
        // catch fetch errors (ie ACCESS to server blocked)
        .catch(err => {
            console.error(err);
        });
    }
    // Attach login_user to the window object, allowing access to form action
    window.login_user = login_user;
@token_required
        def post(self, current_user): # Create method
            ''' Read data for json body '''
            body = request.get_json()
            
            ''' Avoid garbage in, error checking '''
            # validate name
            name = body.get('name')
            if name is None or len(name) < 2:
                return {'message': f'Name is missing, or is less than 2 characters'}, 400
            # validate uid
            uid = body.get('uid')
            if uid is None or len(uid) < 2:
                return {'message': f'User ID is missing, or is less than 2 characters'}, 400
            # look for password and dob
            password = body.get('password')
            dob = body.get('dob')
            ''' #1: Key code block, setup USER OBJECT '''
            uo = User(name=name, 
                      uid=uid)
            
            ''' Additional garbage error checking '''
            # set password if provided
            if password is not None:
                uo.set_password(password)
            # convert to date type
            if dob is not None:
                try:
                    uo.dob = datetime.strptime(dob, '%Y-%m-%d').date()
                except:
                    return {'message': f'Date of birth format error {dob}, must be mm-dd-yyyy'}, 400
# This is code from the user.py in the model
def create(self):
    try:
        # creates a person object from User(db.Model) class, passes initializers
        db.session.add(self)  # add prepares to persist person object to Users table
        db.session.commit()  # SqlAlchemy "unit of work pattern" requires a manual commit
        return self
    except IntegrityError:
        db.session.remove()
        return None
    // uri variable and options object are obtained from config.js
    import { uri, options } from '/CompSci/assets/js/api/config.js';
    function login_user(){
        // Set Authenticate endpoint
        const url = uri + '/api/users/authenticate';
        // Set the body of the request to include login data from the DOM
        const body = {
            name: document.getElementById("name").value,
            uid: document.getElementById("uid").value,
            password: document.getElementById("password").value,
            dob: document.getElementById("dob").value
        };
        // Change options according to Authentication requirements
        const authOptions = {
            ...options, // This will copy all properties from options
            method: 'POST', // Override the method property
            cache: 'no-cache', // Set the cache property
            body: JSON.stringify(body)
        };
        // Fetch JWT
        fetch(url, authOptions)
        .then(response => {
            // handle error response from Web API
            if (!response.ok) {
                const errorMsg = 'Login error: ' + response.status;
                console.log(errorMsg);
                return;
            }
            // Success!!!
            // Redirect to the database page
            window.location.href = "/CompSci/data/database";
        })
        // catch fetch errors (ie ACCESS to server blocked)
        .catch(err => {
            console.error(err);
        });
    }
def post(self):
          try:
              body = request.get_json()
              if not body:
                  return {
                      "message": "Please provide user details",
                      "data": None,
                      "error": "Bad request"
                  }, 400
              ''' Get Data '''
              uid = body.get('uid')
              if uid is None:
                  return {'message': f'User ID is missing'}, 400
              password = body.get('password')
                
              ''' Find user '''
              user = User.query.filter_by(_uid=uid).first()
              if user is None or not user.is_password(password):
                  return {'message': f"Invalid user id or password"}, 400
              if user:
                  try:
                      token = jwt.encode(
                          {"_uid": user._uid},
                          current_app.config["SECRET_KEY"],
                          algorithm="HS256"
                      )
                      resp = Response("Authentication for %s successful" % (user._uid))
                      resp.set_cookie("jwt", token,
                              max_age=3600,
                              secure=True,
                              httponly=True,
                              path='/',
                              samesite='None'  # This is the key part for cross-site requests
                              # domain="frontend.com"
                              )
                      return resp
    fetch(url, authOptions)
    function login_user(){
        // Set Authenticate endpoint
        const url = uri + '/api/users/';
        // Set the body of the request to include login data from the DOM
        const body = {
            uid: document.getElementById("uid").value,
            dob: document.getElementById("dob").value,
            favfood: document.getElementById("favfood").value
        };
        // Change options according to Authentication requirements
        const authOptions = {
            ...options, // This will copy all properties from options
            method: 'PUT', // Override the method property
            cache: 'no-cache', // Set the cache property
            body: JSON.stringify(body)
        };
        // Fetch JWT
        fetch(url, authOptions)
        .then(response => {
            // handle error response from Web API
            if (!response.ok) {
                const errorMsg = 'Login error: ' + response.status;
                console.log(errorMsg);
                return;
            }
            // Success!!!
            // Redirect to the database page
            window.location.href = "/CompSci/data/database";
        })
        // catch fetch errors (ie ACCESS to server blocked)
        .catch(err => {
            console.error(err);
        });
    }
    // Attach login_user to the window object, allowing access to form action
    window.login_user = login_user;
  @token_required
  def put(self, current_user):
      body = request.get_json() # get the body of the request
      uid = body.get('uid') # get the UID (Know what to reference)
      dob = body.get('dob')
      if dob is not None:
          try:
              fdob = datetime.strptime(dob, '%Y-%m-%d').date()
          except:
              return {'message': f'Date of birth format error {dob}, must be mm-dd-yyyy'}, 400
      users = User.query.all()
      for user in users:
          if user.uid == uid:
              user.update('','','',fdob)
      return f"{user.read()} Updated"
const authOptions = {
    ...options, // This will copy all properties from options
    cache: 'no-cache',
    method: 'DELETE',
    mode: 'cors',
    headers: {
        'Content-Type': 'application/json',
        // 'Access-Control-Allow-Origin': '*'
    },
};
// Fetch JWT
fetch(url, authOptions)
.then(response => {
    // handle error response from Web API
    if (!response.ok) {
        const errorMsg = 'Login error: ' + response.status;
        console.log(errorMsg);
        return;
    }
def delete(self, current_user):
  body = request.get_json()
  uid = body.get('uid')
  users = User.query.all()
  for user in users:
      if user.uid == uid:
          user.delete()
  return jsonify(users.read())