package json bin field

We can define some executable js file in the bin section of the package json so that during installation, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.

The file js need to start with the node flavor hash ban : #!/usr/bin/env node,  where the env will file the path of node in the system for us.

And npm will also add the ./node_modules/.bin into the PATH for its script section so if we define something like `{ “bin” : { “myapp” : “./cli.js” } }`. Then in the `script` we just need to define:

run-myapp: myapp. rather than run-myapp: ./node_modules/.bin/myapp.

Advertisements

more understanding on css transition

A transition occurs when a CSS property changes from one value to another value over a period of time.

You can create CSS Transitions with the transition property:

.selector {
  transition: property duration transition-timing-function delay;
}

The transition property is a shorthand of four CSS properties, transition-propertytransition-durationtransition-timing-functiontransition-delay.

.selector {
  transition-property: property;
  transition-duration: duration;
  transition-timing-function: timing-function;
  transition-delay: delay

  /* The transition property is the shorthand for the above four properties */
  transition: property duration timing-function delay;
}

transition-property refers to the CSS property you wish to transition. It is required in the transition shorthand.

transition-duration refers to the duration of the transition. How long do you want the transition to last? This value is written in seconds with the s suffix (like 3s). It is also required in the transitionshorthand.

transition-timing-function refers to how to transition occurs. You’ll learn more about this later.

transition-delay refers to how long you want to wait before starting the duration. This value is written in seconds with the s suffix (like 3s). transition-delay is optional in the transition shorthand.

Triggering transitions

You can trigger CSS transitions directly with pseudo classes like :hover(activates when mouse goes over an element), :focus (activates when a user tabs onto an element, or when a user clicks into an input element), or :active (activates when user clicks on the element).

/* creating transitions directly in CSS */
.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button:hover {
  background-color: #1ce;
}

You can also trigger CSS transitions through JavaScript by adding or removing a class.

.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button.is-active {
  color: #1ce;
}
const button = document.querySelector('.button')
button.addEventListener('click', _ => button.classList.toggle('is-active'))

Understanding transition-timing-function

The transition-timing-function governs how a transition occurs. All transitions have a value of linear by default, which means the property changes evenly until the end of the transition.

.selector {
  transition: transform 1s linear;

  /* OR */
  transition-property: transform;
  transition-duration: 1s;
  transition-timing-function: linear;
}

The thing is, nothing moves linearly in life. That’s not how real objects move. Sometimes, we accelerate; sometimes, we decelerate. The transition-timing-function allows you to capture all of that.

Imagine yourself throwing a tennis ball into an open field. The ball leaves your hand with the maximum speed. As it moves, it loses energy, it decelerates and eventually comes to a halt. This is called ease-out. There’s a timing function for it.

.selector {
  transition-timing-function: ease-out;
}

Now imagine you’re in a car. It’s not moving right now. When you move the car, it accelerates and goes toward its top speed. This is called ease-in. There’s also a timing function for it.

.selector {
  transition-timing-function: ease-in;
}

Since you have ease-in and ease-out, there’s also a timing function that combines the two together, ease-in-out. (I advise against using ease-in-out in your transitions unless your transitions last longer than a second. Nothing eases in and out within a second. It simply looks weird.)

.selector {
  transition-timing-function: ease-in-out;
}

Transitioning two or more properties

You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property.

You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.

.selector {
  transition: background-color 1s ease-out,
              color 1s ease-out;

  /* OR */
  transition-property: background, color;
  transition-duration: 1s;
  transition-timing-function: ease-out;
}

You may be tempted to transition every CSS property with all. Don’t ever do this. This is bad for performance. Always specify the property you’re trying to transition.

/* DON'T EVER DO THIS */
.selector {
  transition-property: all
}

/* ALWAYS DO THIS */
.selector {
  transition-property: background-color, color, transform;
}

Transitioning in vs transitioning out

Sometimes, you want the properties to transition in and out at differently. You want the duration, timing-function or delay to be different.

To do so, you write another set of transition- properties.

.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button:hover {
  background-color: #1ce;
  transition-duration: 2s;
}

When you write transition properties in the triggering (pseudo) class, the transition properties in the triggering class overwrites the original transition properties you’ve stated in the base class.

So, in the example above, when you hover on the button, the background color takes 2 seconds to change from #33ae74 to #1ce.

When you hover out from the button, the background color only takes 0.5s to change back to #1ce because the transition-duration of 2s no longer exists.

FROM HERE, a great article!

Akamai CloudFront Certificate pinning

We recently took over a project that has some static angularJS code hosted in via standard Route 53 -> CloudFront -> S3. And domain CDN is using Akamai which has origin set to the R53 url. Akamai has a `Specific Certificates (pinning)` setting to pull certificate from a *.cloudfront.net. 

Over the weekend something odd happened, some of our users can access, some get Akamai error, some get 404. Turns out the reason is the CloudFront certificate expires and amazon signed a new one. However in our Akamai side, we still hold that old cert’s hash which is used for ssl validation. As a result the ssl connection cannot be established. To solve the issue we have to re-extract the hash for new certificate in Akamai console. And it worked in our QA. The time we are ready to apply this change  to prod, our prod suddenly worked… We believe Akamai also have some mechanism to periodically pull the site for new certificate chain, or the max-age of the old hash reached.

A final solution will be create a new cert with R53 domain name to avoid all these pin/expire issue.

Certificate Pinning is basically allow us to ignore the regular SSL certificate chain verification process and just/only trust the provided certs. For Akamai, it generates the SHA-1 fingerprint of the leaf cert in the chain and use that to compare on each SSL handshake.

This link show chrome/Symantec is working on phasing out Symantec issued certs( Certs signed with Dec 1st 2017 or later are still good).

macos system launch config

MacOS Config options

MacOS boot service is mainly configured via three ways:
1.  the system preferences -> Users & Groups -> Login items
2. /System/Library/StartupItems and /Library/StartupItems/
3. launchd system initialization process configuration.

The first two are relatively simple, we will focus mainly on the third more complex launchd configuration optimization.
launchd is a key process for initializing the system environment under Mac OS. Similar to Linux under init, rc.

MacOS Boot Flow

Let’s take a look at the MacOS startup flow:
1, mac firmware activation, initialize hardware, load BootX boot.
2, BootX load kernel and kernel extension (kext).
3, the kernel starts the launchd process.
4, launchd Start the service daemon by following the plist configuration in the /System/Library/LaunchAgents,  System/Library/LaunchDaemons, ?/Library/LaunchDaemons, ?Library/LaunchAgents, ~/Library/LaunchAgents.

The five launch DIRs

After going thru the Mac OS startup flow, we can see that the plist files in the below five directories  ?/System/Library/LaunchAgents, ?/System/Library/LaunchDaemons, ?/Library/LaunchDaemons, ?Library/LaunchAgents?, ~/Library/LaunchAgents. are key to the system optimization.

some basic concepts

difference between/System/Library and /Library and ~/Library directory?

/System/Library directory is stored in Apple’s own software development.
The /Library directory is the third-party software that the system administrator holds.
~/Library/ is the user’s own third-party software.

What is the difference between LaunchDaemons and LaunchAgents?

LaunchDaemons is the service (daemon) that the user started before the login.
LaunchAgents is the service (daemon) that the user starts after landing.

SPEC

plist file format and the meaning of each field in the above mentioned five directories:

KEY DESCRIPTION REQUIRED
Label The name of the job yes
ProgramArguments Strings to pass to the program when it is executed yes
UserName The job will be run as the given user, who may not necessarily be the one who submitted it to launchd. no
inetdCompatibility Indicates that the daemon anticip to be run as if it were launched by? Inetd no
Program The path to your executable. This key can save the ProgramArguments key for flags and arguments. no
onDemand A? Boolean? Flag that defined if a job runs continuously or not no
RootDirectory The job will be? Chrooted? Into another directory no
ServiceIPC Any the daemon can speak IPC to launchd no
WatchPaths Allows launchd to start a job based on modifications at a file-system path no
QueueDirectories Similar to WatchPath, a queue will only watch an empty directory for new files no
StartInterval Used to schedule a job that runs on a repeating schedule. Specified as the number of seconds to wait between runs. no
StartCalendarInterval Job scheduling. The syntax is similar to cron. no
HardResourceLimits Controls restriction on the resources consumed by any job no
LowPriorityIO Tells the kernel that this task is of a low priority when doing file system I / O no
Sockets An array can be used to specify what socket the daemon will listen on for launch on demand no

Do not understand the above plist configuration? It is fine. Our optimization strategy is completely unload the service, so we do not care that much about plist in the configuration meaning.

Leverage launchctl

To start to optimize the disabled service, we need to use the Mac OS provides a tool instruction- launchctl
The launchctl directive sets a disable flag for the service. When launchd starts, it checks whether the service is disabled or not to determine whether the service needs to be enabled.

Method 1 to disable service

First find the disabled flag file /var/db/launchd.db/com.apple.launchd/overrides.plist to see if the service you want to disable has been disabled.
Some services have been disabled but are not listed in overrides.plist. At this point, you also need to check the service plist file Label field has been marked as Disable.

After confirming that the service is not disabled, we can disable the service by invoking the following command:
sudo launchctl unload plist-file-path

For example, I would like to disable spotlight :

sudo launchctl unload /System/Library/LaunchAgents/com.apple.Spotlight.plist

After disabling the service, restart Mac OS to take effect.

Method of banning service 2

a more effective and violent method (recommended)
Uninstall the service first
sudo launchctl unload /System/Library/LaunchAgents/com.apple.Spotlight.plist
And then the plist file mv to other directory backup. Reboot. Done.

I personally prefer this way to disable the service, so recommend it.

If you find that the service is disabled, the system or software is abnormal, you can restore the service by putting the file back to the original folder and run the following command:
sudo launchctl load plist-file-path

Note: Be very careful when disabling System-level service,. please get familiar what that system service does and do enough research before remove/disable it. Otherwise it may cause the system to fail to start. The safest thing to do is to stop it.

On the other hand for the user service, we can rest assured that we could disable, in case there are problems we just need to re-enable it.

Here is a list of my disabled services:
/Library/LaunchDaemons/com.google.keystone.daemon.plist? (Google Software Update)
/Library/LaunchAgents/com.google.keystone.root.agent? (Google Software Update)
~ / Library / LaunchAgents / com.google.keystone.agent.plist? (Google Software Update, users do not need to add the process of sudo)
~ / Library / LaunchAgents / com.apple.CSConfigDotMacCert-ken.wug \ @ me.com-SharedServices.Agent.plist (me.com’s shared services, I do not have)
/System/Library/LaunchDaemons/org.cups.cupsd.plist (printer)
/System/Library/LaunchDaemons/org.cups.cups-lpd.plist (printer)
/System/Library/LaunchDaemons/com.apple.blued.plist (bluetooth)
/System/Library/LaunchAgents/com.apple.AirPortBaseStationAgent.plist (apple wireless base station, i do not have this device)

I know the daemon (service) name, how to find the corresponding plist file?
Copy the process (service) name, and then to / System / Library / LaunchAgents,? / System / Library / LaunchDaemons,? / Library / LaunchDaemons,? Library / LaunchAgents, ~ / Library / LaunchAgents five directories, through the following command :

ll | grep process(service)-name such as
ll | grep blued
Found it in /System/Library/LaunchDaemons Next, follow the steps outlined above to disable the service

For McAfee

For React Native local development in iOS, i have to disable Mcafee daemon to free the 8081 port. For android, we can do the workaround by using 8088.

 cd /Library/LaunchDaemons
 sudo launchctl unload com.mcafee.agent.macmn.plist

polygon in svg and css

in svg we can create triangle like below

<svg height="210" width="500">
  <polygon points="200,10 250,195 160,210" style="fill:lime;stroke:purple;stroke-width:1" />
  Sorry, your browser does not support inline SVG.
</svg>

turns out in css, we have similar stuff called clip-path which take similar parameter and draw the shape.

clip-path: polygon(50% 0%, 0% 100%, 100% 100%);

For circle/ellipse, it has specific function, circle and ellipse.

We can do something like

clip-path: circle(50% at 50% 50%);
Or
clip-path: circle(50px at 50px 50px) means at(50px, 50px),clip a circle with radius 50px.

More example here.

Or a 中文文章

debug hover item in chrome devtools

Chrome devtools is our friend, always.

Today when I was developing an angular 4.x app with primeng library, i have to check the class set on the tooltip component. As we know the tooltip is hover event based, so if we hover on it to make it showup and then shift our focus to the dev tool element tab, the tooptip would disappear.

Chrome tool has a feature to activate the hover stuff(:hover) on specific element for CSS sake. It is quite handy but obviously it does not apply in this use case since this tooltip is js based.

Search around and finally find a solution: using F8 or CMD + \ which is pause the script execution.

Steps are quite straightforward:

Mouse over the tooltip, and press F8 while it is displayed.

Now you can now use the inspector to look at the CSS.

LDAP notes on Forgerock OpenDJ

Forgerock has a good explanation on their openDJ, LDAP, DS etc…

Below are some of my notes.

LDAP directory data is organized into entries, similar to the entries for words in the dictionary, or for subscriber names in the phone book.

dn: uid=bjensen,ou=People,dc=example,dc=com
uid: bjensen
cn: Babs Jensen
cn: Barbara Jensen
facsimileTelephoneNumber: +1 408 555 1992
gidNumber: 1000
givenName: Barbara
homeDirectory: /home/bjensen
l: San Francisco
mail: bjensen@example.com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: top
ou: People
ou: Product Development
roomNumber: 0209
sn: Jensen
telephoneNumber: +1 408 555 1862
uidNumber: 1076

The entry also has a unique identifier, shown at the top of the entry, dn:uid=bjensen,ou=People,dc=example,dc=com. DN is an acronym for distinguished name. No two entries in the directory have the same distinguished name. Yet, DNs are typically composed of case-insensitive attributes.

When you look up her entry in the directory, you specify one or more attributes and values to match. The directory server then returns entries with attribute values that match what you specified.

A directory server stores two kinds of attributes in a directory entry: user attributes and operational attributes. User attributes hold the information for users of the directory. All of the attributes shown in the entry at the outset of this section are user attributes. Operational attributes hold information used by the directory itself. Examples of operational attributes include entryUUID, modifyTimestamp, and subschemaSubentry. When an LDAP search operation finds an entry in the directory, the directory server returns all the visible user attributes unless the search request restricts the list of attributes by specifying those attributes explicitly. The directory server does not, however, return any operational attributes unless the search request specifically asks for them. Generally speaking, applications should change only user attributes, and leave updates of operational attributes to the server, relying on public directory server interfaces to change server behavior. An exception is access control instruction (aci) attributes, which are operational attributes used to control access to directory data.

 

You may be used to web service client server communication, where each time the web client has something to request of the web server, a connection is set up and then torn down. LDAP has a different model. In LDAP the client application connects to the server and authenticates, then requests any number of operations, perhaps processing results in between requests, and finally disconnects when done.