MS, Leave My Settings Alone

What with limited formal education and an IQ score only moderately above average, I have no trouble discerning the manipulative tactics of Microsoft. Their kindergarten psychology used to keep you attached to, and dependent upon, their proprietary products is less than amusing. This tit for tat, childish approach Of MS at keeping you 100% 'in the fold' is becoming quite tiresome, to say the least.

My issue today is file type association. As far back as XP (and possibly before) file type associations were set in the Control Panel. Once set with your preferences, they had a tendency to stay at those desired settings.

Windows 10 uses Settings instead of Control Panel as a place to make changes to file type associations. While I see no benefit in this change, I have no problems with it. I don't care where I designate my preferences as long as I'm able to make them and keep them.

In the good old days, when I set my file type associations, they stayed the way I set them. Update after update, they stayed the way I set them.

Now, with Windows 10, things are different. Every time MS has the occasion to tinker with my machine, updates and such, I find I need to reset associations all over again.

MS, do know this. I chose VLC and MPC-HC as my media player for most formats simply because WMP would not play them, or at least not without third party codecs.

I chose (free) VLC and (free) MPC-HC to play my media files because they do so without any hassle. Apparently, made a choice that doesn't set well with MS,

But please, can we be adults about this matter. When updates are installed, I soon find I am being asked what app I want to play mp3s, flacs, wavs, mp4s, jpgs, png, and the list goes on. I am offered a list of apps to choose from with Windows apps at the top of the list. From there, the list includes app that wont even play the format in question. This is childish.

MS makes me hunt for the particular app I want as it is not on the presented list. The very same app I've set as my choice many times over. Why is it so difficult to leave my settings alone? Not everyone is interested in being a Windows insider.

Upon notification of the last two updates, I was informed they contained some very good things. I was presented with a link to see just what these good things were. The link provided no such thing. It did offer another link to where I would have to get an app to be able to see those 'good things". By now, I've lost all interest. If I have to acquire a special app just to get MS to tell me the what's in the latest updates...to hell with it. This is carrying proprietorship a bit too far.

As for my app settings, I know what is best for me. I will continue to change them back to my choices as often as they are switched from my choices. Childish tit for tat.

How to Encrypt and Decrypt Text Strings with JavaScript

In one of my web projects, I require simple and easy-to-implement encryption and decryption JavaScript library that could encode a piece of text and then decode the encoded string on the server-side.

The easiest option is the base64 encoding scheme that can be easily implemented in both native JavaScript and Google Apps Script.

Base64 Encoding with Google Apps Script

const base64Encode = text => {
  const base64data = Utilities.base64Encode(text, Utilities.Charset.UTF_8);
  return base64data;
};

const base64Decode = base64data => {
  const decoded = Utilities.base64Decode(base64data, Utilities.Charset.UTF_8);
  const input = Utilities.newBlob(decoded).getDataAsString();
  return input;
};

Base64 Encoding with JavaScript

const CryptoJS = require('crypto-js');

const encrypt = text => {
  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text));
};

const decrypt = data => {
  return CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8);
};

The obvious downside is that Base64 is encoding (not encryption) and the Base64 strings can be easily decoded.

If you are looking for a secure encryption algorithm that would require a secret passphrase for decrypting the encrypted text, go with AES. It generates longer strings but they cannot be decrypted without the password.

AES Plain Text Encryption & Decryption

const CryptoJS = require('crypto-js');

const encryptWithAES = text => {
  const passphrase = '123';
  return CryptoJS.AES.encrypt(text, passphrase).toString();
};

const decryptWithAES = ciphertext => {
  const passphrase = '123';
  const bytes = CryptoJS.AES.decrypt(ciphertext, passphrase);
  const originalText = bytes.toString(CryptoJS.enc.Utf8);
  return originalText;
};

AES Encrypt & Decryption with Google Apps Script

If you would like to use the AES encryption algorithm with Google Apps Script, use the Apps Script Starter to import the CryptoJS package in your project as shown in this example.

import AES from 'crypto-js/aes';
import Utf8 from 'crypto-js/enc-utf8';

const encryptWithAES = (text, passphrase) => {
  return AES.encrypt(text, passphrase).toString();
};

const decryptWithAES = (ciphertext, passphrase) => {
  const bytes = AES.decrypt(ciphertext, passphrase);
  const originalText = bytes.toString(Utf8);
  return originalText;
};

global.testAES = () => {
  const inputText = 'Hello World';
  const passphrase = 'My Secret Passphrase';

  Logger.log({ inputText });

  const encryptedText = encryptWithAES(inputText, passphrase);
  Logger.log({ encryptedText });

  const decryptedText = decryptWithAES(encryptedText, passphrase);
  Logger.log({ decryptedText });
};

Alternatively, for Google Apps Script, the cCryptoGS library can also be used to implement AES encryption in your projects and Suite add-ons. To get started, go to Resources -> Libraries and add the MSJnPeIon6nzdLewGV60xWqi_d-phDA33 library to your Google Script project.

const encryptedMessage = cCryptoGS.CryptoJS.AES.encrypt('message', 'passphrase').toString();
Logger.log(encryptedMessage);

const decryptedMessage = cCryptoGS.CryptoJS.AES.decrypt(encryptedMessage, 'passphrase').toString(
  CryptoJS.enc.Utf8
);
Logger.log(decryptedMessage);

Block All Incoming and Outgoing Emails Except Specific Whitelisted Domains

The finance team in an organization would like to use Gmail for internal communication only. The corporate email policy restricts the finance team from sharing any files or email messages with external teams but the employees are allowed to exchange emails within the team.

Google makes it easy to implement such an email policy in Gmail for GSuite customers.

Block Incoming Emails in Gmail

To get started, sign-in to admin.google.com as your GSuite domain admin and go to Apps > GSuite Core Services > Gmail > Advanced Settings.

Inside the General Settings tab, navigate to Restrict Delivery and click the Configure button to restrict the domains that your employees are allowed to exchange emails with.

Under the Add addresses section, specify one or more domains and email addresses that employees are allowed to send and receive email messages from.

Whitelist domains and email addresses in Gmail

You can specify inputs in the following format:

  1. harvard.edu - Allow emails from everyone in the domain
  2. *.harvard.edu - Allow emails from all subdomains
  3. finance.harvard.edu - Allow emails from a specific subdomain
  4. admin@harvard.edu - Allow emails from an email address

When adding domains in the whitelist, it is recommended that you turn on sender authentication to disallow spoofed emails (where the actual sender is different from the FROM address mentioned in the email header). Gmail uses the SPF and DKIM records to verify if the sender is authenticated.

Save the settings and employees would be limited to sending emails to specific domains only.

Google’s New ML-Powered Voice Recording App

Google is heavily investing its resources in AI and machine learning research intending to shell out products and services for the future. So whether it has to do with computational photography or email suggestion features, Google has always been active on this front. Recently, Google also launched the famed “Google Recorder”. You might wonder that there are several voice recorder apps in the market so why this? But we all know it, if it is from Google it has to be a contender for the top slot! 

Before we explore further, let us see whether Google reads the race or not! And, yes we see right there that Google has done a great job when it comes to AI-based research and launches. 

New Change FX Launches Foreign Exchange API Suite

New Change FX (NCFX), a regulated benchmark administrator, has introduced a new suite of Foreign Exchange APIs. The suite includes three categories of APIs: NCFX Data APIs, NCFX Calculation APIs, and NCFX Model APIs. This means that customers are an API call away from NCFX benchmark data, calculations, and models.

What to Use Instead of Number Inputs

You might reach for <input type="number> when you're, you know, trying to collect a number in a form. But it's got all sorts of issues. For one, sometimes what you want kinda looks like a number, but isn't one (like how a credit card number has spaces), because it's really just a string of numbers. Even more importantly, there are a variety of screen reader problems.

Hanna Laakso documents the problems for GOV.UK. This is what they landed on:

<input type="text" inputmode="numeric" pattern="[0-9]*">

The inputmode attribute is pretty great, and we have a deep dive on that.

Phil Nash came to (almost) same exact conclusion, and blogged about improving the experience of a two-factor auth code input on the Twilio blog:

<input
  type="text"
  name="token"
  id="token"
  inputmode="numeric"
  pattern="[0-9]*"
  autocomplete="one-time-code"
/>

That last attribute is interesting and new to me. It means you get this super extra useful experience on browsers that support it:

iOS screen with a numeric input and a text message offering to auto-fill the two-factor auth

There are other autocomplete values, as Phil writes:

There are many autocomplete values available, covering everything from names and addresses to credit cards and other account details. For sign up and login there are a few autocomplete values that stand out as useful hints: usernameemailnew-passwordcurrent-password.

Browsers and password managers have very good heuristics to find login forms on web pages, but using the username and current-password values make it very obvious. 

The post What to Use Instead of Number Inputs appeared first on CSS-Tricks.

Currying in CSS

Funny timing on this I was just looking at the website for Utopia (which is a responsive type project which I hate to admit I don't fully understand) and I came across some CSS they show off that looked like this:

:root {
  --fluid-max-negative: (1 / var(--fluid-max-ratio) / var(--fluid-max-ratio));
  --fluid-min-negative: (1 / var(--fluid-min-ratio) / var(--fluid-min-ratio));
 
  ...
}

See anything weird there? That code is using mathematical operators, but there is no calc() function wrapped around it.

Just as my curiosity set in, Trys Mudford, a creator of Utopia, blogged it:

The value after the : in the CSS custom property does not have to be valid CSS. It won’t cause any errors, nor invalidate the custom property. It won’t be evaluated in the browser until used, or more specifically, placed in a calc() function.

Here's a contrived example:

:root {
  --padding: 1rem;
  
  /* These are meaningless alone */
  --padding-S: var(--padding) / 2;
  --padding-L: var(--padding) * 2;
}

.module--large {
  /* But they evaluate once they are in a calc() */
  padding: calc(var(--padding-L));
}

In my limited understanding, currying is like functions that return functions. I suppose this is sorta like that in that the alternate padding properties above are sort of like derivative functions of the main padding function (if you can call it that), and you only call them and execute them as needed.

The post Currying in CSS appeared first on CSS-Tricks.

Easy OAuth 2.0 Single Sign-on in Java

Different applications need different permissions. Although you might have a single resource server providing data to multiple apps, it’s often the case that you don’t want all users of application A to access application B. 

In this tutorial, you’ll learn how to use Okta and Spring Boot to implement SSO with two client applications and a single resource server. You’ll also learn how to restrict access to the resource server based on app scores and how to use access policies to enforce authentication and authorization rules.

BracketSpace Releases Library of Reusable Code for Plugin and Theme Development

BracketSpace, a WordPress-centric software development company based, released Micropackage a few weeks ago. The project is a collection of open-source repositories with reusable code for inclusion in WordPress plugins and themes. The library currently has 13 packages, including a filesystem wrapper, a template system, an Advanced Custom Fields block creator, and more.

The company out of Poland specializes in project outsourcing and plugin development. Some of their more popular plugins include Advanced Cron Manager Pro and Notification, a custom notification plugin in which the BracketSpace sells pro extensions for various services.

The Micropackage project was driven by the needs of the team and its projects. “We started the Micropackage project to scratch our own itch,” said Jakub Mikita, CEO of BracketSpace. “During the past few years of active plugin and website development, we noticed that keeping the code standard was very important for maintainability.” The BracketSpace team had been copying and pasting code between projects. Eventually, the team asked themselves the inevitable question that most development teams come to — why not break all of this code up into small packages and maintain them in a single place? Thus, the Micropackage project was born.

BracketSpace is using all of the packages in many of its current plugins and themes because the code was originally taken from those projects. “We are now rewriting one of our flagship plugins, Notification, using the micropackages and intend to create every new plugin and theme using them,” said Mikita. “And, because they are loosely coupled, there can be a lot of configuration variations.

Package and dependency management is a standard part of development within the larger PHP development world. The use of packages has become more and more standard as WordPress has begun using modern JavaScript tooling. However, the ecosystem mostly falls short when dealing with PHP packages. While many plugin developers make use of such dependencies, the practice is not common. WordPress also has no built-in method of handling dependencies. The situation makes it hard for projects such as Micropackage to gain any real traction within the overall WordPress developer community.

The Available Packages

The project includes 13 repositories that can be included in WordPress plugins or themes via Composer. Most of the packages are currently available on the Micropackage page on Packagist. Several of the packages are essentially wrappers for various WordPress APIs for simpler usage. However, some of the packages offer new developer features.

Mikita said the following are the most important packages for the team:

  • DocHooks – PHP comment annotations repo that supports filters, actions, and shortcodes.
  • Requirements – Environment requirement checker for plugins.
  • Filesystem – Simplified wrapper around the WordPress Filesystem API.
  • Templates – Basic PHP templating solution that supports passing data to templates.
  • Responsive Embeds – JavaScript package for automatically making any embed responsive.

The repositories don’t stop there. They have built other wrappers for WordPress APIs, such as caching, scripts, and internationalization. The team also has a block creator for ACF that allows developers to create blocks from templates.

BracketSpace has at least five more packages planned for the project. At the moment, the packages have primarily targeted WordPress developers. However, Mikita said the team will also create platform-agnostic repositories whenever possible. That way, they will be useful for developers beyond the WordPress ecosystem.

How to Integrate Jenkins With GitHub

Jenkins has become one of the most popular tools to create CI/CD pipelines. There are many reasons for this, and one is the number of plugins and integrations that allow users to work with almost any tool or platform out there. When you use a plugin, you only have to set some parameters like credentials. For instance, you could use a plugin to deploy your infrastructure to AWS or Azure. Or you could use the GitHub plugin to use Git as a repository for application or infrastructure code — you've come here for this, I know.

Git is an essential plugin that everyone working with Jenkins will need. You can get to the point of configuring a Jenkins job only once. Then, all subsequent changes for the delivery pipeline can be done using a version control system like Git. Are you wondering how to do this? You've come to the correct place; I'll show you how to integrate Jenkins with GitHub step by step.

Compile Protocol Buffers Using Maven

Hi folks! In this article, we will explore how to compile protocol buffers using Maven. We assume the reader has a basic idea about protocol buffers and Maven.

Google developed protocol buffers for use in their internal services. It is a binary encoding format that allows you to specify a schema for your data using a specification language, like so:

How to Test for Lock Table Consistency When Deploying High Availability for SAP ERP

Implementing high-availability capabilities for SAP ERP systems can be a complex undertaking. But the importance of high availability in keeping companies “open for business” can’t be overstated. Applications and servers will fail. Power outages will occur, and a natural disaster may strike at any time. 

This article provides technical guidance on two key steps in the process to implement high availability for SAP ERP systems: 

API Security Weekly: Issue #73

This week, we check how Tinder’s API vulnerability has developed a life of its own, the latest statistics from Akamai on API security, the best current practices for JWT, and why API security needs both API firewalls and API management, not just either-or.

Vulnerability: Tinder

Back in July 2019, we covered the OWASP API3:2019 — Excessive data exposure vulnerability in Tinder APIs. The premium features, such as unblurred images of those who like you, were not enforced on API-level. Thus, a suitable crafted request to the API could by-pass these restrictions.

Creating a Modal Image Gallery With Bootstrap Components

Have you ever clicked on an image on a webpage that opens up a larger version of the image with navigation to view other photos?

Some folks call it a pop-up. Others call it a lightbox. Bootstrap calls it a modal. I mention Bootstrap because I want to use it to make the same sort of thing. So, let’s call it a modal from here on out.

Why Bootstrap? you might ask. Well, a few reasons:

  • I’m already using Bootstrap on the site where I want this effect, so there’s no additional overhead in terms of loading resources.
  • I want something where I have complete and easy control over aesthetics. Bootstrap is a clean slate compared to most modal plugins I’ve come across.
  • The functionality I need is fairly simple. There isn’t much to be gained by coding everything from scratch. I consider the time I save using the Bootstrap framework to be more beneficial than any potential drawbacks.

Here’s where we’ll end up:

Let’s go through that, bit by bit.

Step 1: Create the image gallery grid

Let’s start with the markup for a grid layout of images. We can use Bootstrap’s grid system for that.

<div class="row" id="gallery">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-1">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-2">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-3">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-4">
  </div>
</div>

Now we need data attributes to make those images interactive. Bootstrap looks at data attributes to figure out which elements should be interactive and what they should do. In this case, we’ll be creating interactions that open the modal component and allow scrolling through the images using the carousel component.

About those data attributes:

  1. We’ll add data-toggle="modal"  and data-target="#exampleModal" to the parent element (#gallery). This makes it so clicking anything in the gallery opens the modal. We should also add the data-target value (#exampleModal) as the ID of the modal itself, but we’ll do that once we get to the modal markup.
  2. Let’s add data-target="#carouselExample"  and a data-slide-to attribute to each image. We could add those to the image wrappers instead, but we’ll go with the images in this post. Later on, we’ll want to use the data-target value (#carouselExample) as the ID for the carousel, so note that for when we get there. The values for data-slide-to are based on the order of the images.

Here’s what we get when we put that together:

<div class="row" id="gallery" data-toggle="modal" data-target="#exampleModal">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-1.jpg" data-target="#carouselExample" data-slide-to="0">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-2.jpg" data-target="#carouselExample" data-slide-to="1">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-3.jpg" data-target="#carouselExample" data-slide-to="2">
  </div>
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-4.jpg" data-target="#carouselExample" data-slide-to="3">
  </div>
</div>

Interested in knowing more about data attributes? Check out the CSS-Tricks guide to them.

Step 2: Make the modal work

This is a carousel inside a modal, both of which are standard Bootstrap components. We’re just nesting one inside the other here. Pretty much a straight copy-and-paste job from the Bootstrap documentation.

Here’s some important parts to watch for though:

  1. The modal ID should match the data-target of the gallery element.
  2. The carousel ID should match the data-target of the images in the gallery.
  3. The carousel slides should match the gallery images and must be in the same order.

Here’s the markup for the modal with our attributes in place:

<!-- Modal markup: https://getbootstrap.com/docs/4.4/components/modal/ -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        
      <!-- Carousel markup goes here -->


      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

We can drop the carousel markup right in there, Voltron style!

<!-- Modal markup: https://getbootstrap.com/docs/4.4/components/modal/ -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        
      <!-- Carousel markup: https://getbootstrap.com/docs/4.4/components/carousel/ -->
      <div id="carouselExample" class="carousel slide" data-ride="carousel">
          <div class="carousel-inner">
            <div class="carousel-item active">
              <img class="d-block w-100" src="/image-1.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="/image-2.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="/image-3.jpg">
            </div>
            <div class="carousel-item">
              <img class="d-block w-100" src="/image-4.jpg">
            </div>
          </div>
          <a class="carousel-control-prev" href="#carouselExample" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
          </a>
          <a class="carousel-control-next" href="#carouselExample" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
          </a>
        </div>
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

Looks like a lot of code, right? Again, it’s basically straight from the Bootstrap docs, only with our attributes and images.

Step 3: Deal with image sizes

This isn’t necessary, but if the images in the carousel have different dimensions, we can crop them with CSS to keep things consistent. Note that we're using Sass here.

// Use Bootstrap breakpoints for consistency.
$bootstrap-sm: 576px;
$bootstrap-md: 768px;
$bootstrap-lg: 992px;
$bootstrap-xl: 1200px;


// Crop thumbnail images.
#gallery {
  img {
    height: 75vw;
    object-fit: cover;
    
    @media (min-width: $bootstrap-sm) {
      height: 35vw;
    }
    
    @media (min-width: $bootstrap-lg) {
      height: 18vw;
    }
  }
}


// Crop images in the coursel
.carousel-item {
  img {
    height: 60vw;
    object-fit: cover;
    
    @media (min-width: $bootstrap-sm) {
      height: 350px;
    }
  }
}

Step 4: Optimize the images

You may have noticed that the markup uses the same image files in the gallery as we do in the modal. That doesn’t need to be the case. In fact, it’s a better idea to use smaller, more performant versions of the images for the gallery. We’re going to be blowing up the images to their full size version anyway in the modal, so there’s no need to have the best quality up front.

The good thing about Bootstrap’s approach here is that we can use different images in the gallery than we do in the modal. They’re not mutually exclusive where they have to point to the same file.

So, for that, I’d suggest updating the gallery markup with lower-quality images:

<div class="row" id="gallery" data-toggle="modal" data-target="#exampleModal">
  <div class="col-12 col-sm-6 col-lg-3">
    <img class="w-100" src="/image-1-small.jpg" data-target="#carouselExample" data-slide-to="0">
  
  <!-- and so on... -->
</div>

That’s it!

The site where I’m using this has already themed Bootstrap. That means everything is already styled to spec. That said, even if you haven't themed Bootstrap you can still easily add custom styles! With this approach (Bootstrap vs. plugins), customization is painless because you have complete control over the markup and Bootstrap styling is relatively sparse.

Here’s the final demo:

The post Creating a Modal Image Gallery With Bootstrap Components appeared first on CSS-Tricks.

The 3 Laws of Serverless

Burke Holland thinks that to "build applications without thinking about servers" is a pretty good way to describe serverless, but...

Nobody really thinks about servers when they are writing their code. I mean, I doubt any developer has ever thrown up their hands and said “Whoa, whoa, whoa. Wait just a minute. We’re not declaring any variables in this joint until I know what server we’re going to be running this on.”

Instead of just one idea wrap it all up, Burke thinks there are three laws:

  1. Law of Furthest Abstraction (I don't really care where my code runs, just that it runs.)
  2. The Law of Inherent Scale (I can hammer this code if I need to, or barely use it at all.)
  3. Law of Least Consumption (I only pay for what I use.)

Direct Link to ArticlePermalink

The post The 3 Laws of Serverless appeared first on CSS-Tricks.