Category: Technology

VSCode — Shortcut for Uppercase and Lowercase Conversion

While you can run a command to convert the selected text to upper (or lower) case, there doesn’t appear to be a quick way to do it. Luckily, you can define your own keyboard shortcuts and map those shortcuts to commands. From the File menu, select “Preferences” and “Keyboard Shortcuts” (or use the Ctrl-K Ctrl-S combo).

In the upper right-hand corner, click this icon to open the custom keyboard shortcut JSON file

Add JSON elements for the shortcuts you want to define — the key combination, the command to run, and on what to run the command

Sample key command bindings:

[
 {
    "key": "ctrl+shift+u",
    "command": "editor.action.transformToUppercase",
    "when": "editorTextFocus"
 },
 {
    "key": "ctrl+shift+l",
    "command": "editor.action.transformToLowercase",
    "when": "editorTextFocus"
 }
]

Save … voila, a keyboard shortcut to change to upper and lower case.

Listing Modules In Dynamically Linked Shared Object Libraries

We had to rebuild a server over the weekend — it’s a lot harder to get Apache and PHP set up when you don’t have root access to just install things from the yum repository. And, unlike the servers where I built httpd and php from source … we basically relayed requests to the Unix admin to have packages installed. One of the confusions during the whole process was that we didn’t know what to use as the module name for PHP to load in the httpd.conf file. The line from our old server (LoadModule php5_module /etc/httpd/modules/libphp5.so) produced an error that there was no such thing to load.

When a library fails to load with some error, I know to use ldd … but I didn’t know there was a way to list out the modules in a library. Fortunately, one of my coworkers had already run nm and listed out the modules — nm -D –defined-only sharedLibraryFile | grep module — and we were able to identify that the libphp5.so that we had wasn’t anything like the one on the old server. By listing the modules for each of the shared object libraries installed by the php package, we got the proper module name for httpd.conf

Testing A New Web Server Without DNS Changes

When migrating to a new server, it’s good to validate site functionality before redirecting users to the new host. i.e. I have anya.rushworth.us set up in the httpd config on both server1 and server2. DNS currently points traffic to server1, but I need to test the site on server2.

Approach #1 – With administrative access to the host

Edit your hosts file – open an administrative command prompt

Edit %SYSTEMROOT%\system32\drivers\etc\hosts and add lines with the IP address WHITESPACE and the hostname(s). E.G.
127.0.0.1 lisatest lisatest.rushworth.us lisatest2 lisatest2.rushworth.us
10.1.2.3 otherhost otherhost.rushworth.us
10.2.3.4 anya anya.rushworth.us

Clear your DNS cache (ipconfig /flushdns) and navigate to the URL. You’ll be directed the IP address from your hosts file instead of the DNS registered address.

Approach #2 – No admin access

Install ModHeader in your Chrome browser and click the extension to modify the headers or install ModHeader in your Firefox browser. Click on the extension icon to set a header value.

Add a “Host” header with the value of the virtual host name you need to test

Navigate to the hostname of the new server – https://server2.rushworth.us – but the web server will receive the Host header you configured in ModHeader and serve the web site based on that host header.

 

Exporting A Microsoft Teams Chat

There’s no export functionality in MS Teams chats and conversations. From Microsoft’s standpoint, this makes sense — customer retention. From the customer standpoint, however? There are times I really want to transfer a conversation elsewhere for some reason. You can copy/paste individual text bubbles. If you only need to get one or two bubbles, manually copying the text is going to be quicker. And, for those with special access, there’s the Security & Compliance discovery export stuff as well as an approach using the Graph API. But for the rest of us general users, there’s no easy way to export the bunch of little chat bubbles that comprise a MS Teams chat.  There is, however, a not-too-hard way to do it in the Teams web client.

I’ll prefix these instructions with a disclaimer – your company may have document retention in Teams. When you export your chat content, you’ll need to maintain appropriate retention policies yourself. In IT, we had a few information categories where retention was “useful life” – we could retain system documentation as long as the system was used. If you’re exporting a chat to keep something you are allowed to keep and then keep it outside of Teams … that’s awesome. If you are trying to keep something the company’s retention policy says should be removed … that’s probably not awesome.

Once you’ve determined that the info you are exporting is OK to export and maintain elsewhere, here’s how to export a Teams chat from within the Teams web client. Step 1, of course, is to lot into Teams at https://teams.microsoft.com and go to the chat you want to export. Scroll up to the top of the chat. If you have a really long chat, it may not be possible to export the entire thing using this approach. I might play around with it in the future, by most of my conversations are in Teams channels so I don’t have a chat that’s more than 30 or so messages.

Once you are at the top of the chat, open the developer tools (ctrl-shift-i in Chrome). Clear the errors — they clutter up the screen.

Paste the following script into the console and hit enter:

var strRunningText = "";
var collectionMessageBubbles = document.querySelectorAll('.message-body-content, .message-datetime');

for (let objMessageBubble of collectionMessageBubbles) {
     strRunningText = strRunningText + "\n" + objMessageBubble.textContent;
}

console.log(strRunningText);

If you have a long series of chat messages, you’ll get some of the chat displayed and a button to copy the entire chat content to your clipboard.

If you have a shorter series of chat messages, you’ll have the text of the chat in the console window. You can highlight it and copy/paste the text elsewhere.

There’s a little cleanup that can be done – the content of the message-datetime elements have a beginning and trailing newline character along with a bunch of whitespace. You can get a cleaner timestamp (but, if you embed code within your messages … which I do … the code sections have a lot of extraneous newlines):

var strRunningText = "";
var collectionMessageBubbles = document.querySelectorAll('.message-body-content, .message-datetime');

for (let objMessageBubble of collectionMessageBubbles) {
     strRunningText = strRunningText + "\n" + objMessageBubble.innerText;
}

console.log(strRunningText);

The same JavaScript works in the Teams channel conversations except the channel conversations tend to be longer … so you’re going to export some subset of the channel conversation around where you are in the web browser.

* I realized, during a multi-person chat last week, that I don’t grab the name of the individual who posted the message to the chat. Grabbing the person’s name should just entail adding the identifier for the name element into the querySelectorAll list … but that’s not something I’ve had an opportunity to check yet.

Dynamically determining AD Page Size

Question — is it possible to dynamically determine the maximum page size when communicating with AD via LDAP? Since the page size (1) changed between versions and (2) can be user-customized … a guess is sub-optimal.

Answer — yes. If only the default query policy is used, search at
CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,*domain naming context* (e.g.
CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=example,DC=com) with a filter like “(&(cn=*))”

Return the ldapAdminLimits attribute. Parse MaxPageSize out of the attribute:

lDAPAdminLimits (13): MaxValRange=1500; MaxReceiveBuffer=10485760; MaxDatagramRecv=4096; MaxPoolThreads=4; MaxResultSetSize=262144; MaxTempTableSize=10000; MaxQueryDuration=120; **MaxPageSize=1000**; MaxNotificationPerConn=5; MaxActiveQueries=20; MaxConnIdleTime=900; InitRecvTimeout=120; MaxConnections=5000;

To find all of the query policies, search at CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,*domain naming context* for (&(objectClass=queryPolicy)) … either research a lot about query policies and figure out how to determine which applies to your connection or take the lowest value and know you’re safe.

Android Outlook Message Sending Failure

I’ve been getting a strange error when trying to send pictures within e-mail messages from my Android phone. I say a strange error because there’s literally one entry that comes back when you search for MessageDeliveryFailedException f5f0 — and no pointer at all as to what might have gone wrong. Just a non-delivery report popping into the Inbox on my phone:

     Technical details
     MessageDeliveryFailedException: Could not deliver the message [len=70, data=50005…C090005] sent at 8/25/2020 10:06:28 PM.Failure code: f5f0

I’ve got a reverse proxy with an application firewall and suspected that was the source of my problems. Mostly because errors caused within the Microsoft Exchange system are generally easy to find online. An oddball error is going to come from an oddball source. And I was right — my application proxy log shows an error each time I attempt to send one of the failed messages.

Edited /etc/httpd/conf.d/mod_security.conf and upped the SecRequestBodyNoFilesLimit. Once Apache HTTPD was restarted, I was able to send my messages without problem.

Discourse Censored Words List

It took an unexpectedly long time to find the censored word list in Discourse. I finally resorted to searching the PRs until I located one where the censored word list was replaced with ‘watched words’ … although there wasn’t any readily apparent watched word list in the configuration either. I was able to locate the meta post regarding the watched word implemented under that PR. It’s hiding under logs?! Under each action (block, censor, require approval, flag), there is a “show words” checkbox that displays the configured words.