Detecting a Credit Card number in a field using JavaScript

Given a field such as <input id="notes" type="text" names="notes"> You can detect a Credit Card number using the following in jQuery. This will detect 15 or 16 digit credit card numbers because of the d{3,4}. To only detect 15 or 16 change that to be only d{3} for 15 or d{4} for 16.

$('#notes').on('input', function() {
    const ccDetected = $('#notes').val().match(/\b(?:\d{4}[ -]?){3}(?=\d{3,4}\b)/gm);
    if (ccDetected) {
        alert('don''t use credit cards!');
    }
});

read more

Update LibreELEC to version 9 for Kodi 18

Kodi version 18 has been released as has LibreELEC version 9.

If you’ve checked for updates on your Raspberry Pi and nothing is showing here’s the solution.

  1. Go to the LibreELEC Add-On
  2. Change Automatic Updates from Auto to Manual
  3. Enable Show Custom Channels and then disable it
  4. From the Update Channelmenu chooseLibreELEC-9.0
  5. Go to Available Versions
  6. Install 9.0.0 (or the latest)
  7. Turn Automatic Updates back on
  8. Repeat when LibreELEC version 10 comes out

read more

SurveyMonkey CX API call

SurveyMonkey has a great new API available that allows you to easily send someone an email programmatically. I ran into some hiccups while setting it up and there’s almost zero documentation out there.

Endpoint: This is provided at the end of setting up a survey. Should look like

https://cx.surveymonkey.com/api/v1/surveys/${fromSurvey}/replies

Headers

name="Content-Type" value="application/json"
name="Authorization" value="Token token=#apiToken#"

Body

{
    "person": {
        "email": "emailAddress",
        "first_name": "first name",
        "last_name": "last name",
        "fields": {
            "Custom Field": ["custom field value"]
        }
    },
    "delay": 0
}

The custom fields must match exactly what you put in your admin and you must pass it in as a list. If you don’t pass a list it won’t register. The delay is the number of days to delay sending the survey.

My full postman request is below with sensitive information redacted.

  "info": {
    "_postman_id": "d16018c3-53d9-4ebd-a47f-61a84505a04d",
    "name": "SurveyMonkey",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Survey Monkey",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json",
            "type": "text"
          },
          {
            "key": "Authorization",
            "value": "Token token=${apiToken}",
            "type": "text"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\r\n  \"person\": {\r\n    \"email\": \"email@gmail.com\",\r\n    \"first_name\": \"First\",\r\n    \"last_name\": \"Last\",\r\n    \"fields\": {\r\n      \"Products\": [\"Acme M500\", \"Acme B7500\"]},\r\n  \"facets\": {\r\n    \"Job ID\": \"1234\"\r\n  },\r\n  \"delay\": 24\r\n}"
        },
        "url": {
          "raw": "https://cx.surveymonkey.com/api/v1/surveys/${fromSurvey}/replies",
          "protocol": "https",
          "host": ["cx", "surveymonkey", "com"],
          "path": ["api", "v1", "surveys", "${fromSurvey}", "replies"]
        }
      },
      "response": []
    }
  ]
}

read more

Updating all sub modules in a git project

This command will find all the submodules in your current git projects and pull down changes from master for each submodule.

git submodule -q foreach git pull -q origin master

Once you pull down changes make sure you push the changes back to your project to see the changes.

What is this actually doing?

git submodule basically gets all the submodules in your project

-q means quiet which means it doesn’t output the name of the submodule as it loops through them. This parameter is not required.

foreach um, it loops through each submodule

git pull -q origin master this pulls down the changes from master on the submodule and doesn’t output the changes. Again, the -q is not required, but will reduce the conole output.

read more

Bash loop through folders recursively and lower case files

This script will loop through all files and folders recursively and make them lower case. Please do not just blindly run this against your intended directory. The echo is there for testing and once you know that works then use the mv command

You can perform any command you’d like after the tr. In my case it’s replace all upper case letters with lower case ones.

If you don’t include the if statement, you’ll get a warning message if it tries to rename to the same case, so that keeps the console clean.

find /home/buschm3/bananas -depth -name '*' -print0 |
while IFS= read -r -d '' src; do
    dst=`dirname "${src}"`/`basename "${src}" | tr '[A-Z]' '[a-z]'`
    echo "$src"
    echo "$dst"
    if [ "${src}" != "${dst}" ]
    then
        #mv "$src" "$dst"
    fi
done

read more

Current request is not of type HttpServletRequest

Ran into this error this week

There was an unexpected error (type=Internal Server Error, status=500). Current request is not of type [org.apache.catalina.servlet4preview.http.HttpServletRequest]: ServletWebRequest: uri=/my/url/

Make sure you imported the correct HttpServletRequest import. I wanted import javax.servlet.http.HttpServletRequest;

read more

Filtering FiveThirtyEight's NFL Forecasting Leaderboard

A group of friends and I have a contest going on FiveThirtyEight’s NFL Forecasting Game Leaderboard and they don’t allow group functionality, so at the end of each week I Ctrl + F on the page to find each of our name’s and update a spreadsheet. Instead of spending 3 minutes once a week I decided to spend 15 minutes and write something that will do it for me.

Just replace the names array with a list of the names in your group

const table = document.getElementById('leaderboard-table-wrap').getElementsByTagName('tr');
Array.from(table).forEach(function(item) {
  const names = ['Matt Busche', 'Random Dude'];
  if (names.indexOf(item.getElementsByClassName('name')[0].textContent) === -1) {
    item.closest('tr').remove();
  }
});

As always you can use a Bookmarklet Creator to add this as a “bookmark” on your address bar to make filtering super easy.

Note: If you can’t find a person, each person needs to acknowledge that they want to publically post their score by visiting the leaderboard page and clicking a link.

read more

Finding md5 hash of file

Fun tip I learned today. If you need to find the md5 hash of a file you can simply user the following command.

certutil -hashfile {path+filename} md5 

certutil is included in windows by default, so you aren’t required to have anything additional installed.

read more

Angular Loading JavaScript file in different environments

If you ever need to load two different files in production vs test, you can add some code to your main.ts file in your Angular project. The existing code includes the if statement and enableProdMode(), but you can easily add in the else to conditionally load a different file. In my case I don’t want google analytics posting to my production account.

import { environment } from './environments/environment';

//create a new element
const script = document.createElement('script');
if (environment.production) {
    enableProdMode();
    script.src = 'analytics.js';
} else {
    script.src = 'test-analytics.js';
}
//append that element into the dom
document.head.appendChild(script);

read more

Java setting tracking mode for session

If you avoid using xml for you configuration files like I do, but don’t want to pass the jsessionid around through the URL you can create a @Bean and use a lambda to set the tracking mode as follows

public class AuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public ServletContextInitializer servletContextInitializer() {
      return servletContext -> {
        servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
      };
    }
}

read more