Monday, 14 May 2018

Sending Office 365 emails with perl - invalid SSL_version

In our case, we are sending an email through Office 365 using Net::SMTP::TLS. But apparently that module is broken and unmaintained. We installed the process on a new machine and ran into the problem.

We are getting this error:

invalid SSL_version specified at C:/Strawberry/perl/vendor/lib/IO/Socket/SSL.pm line 444


We were able get it running using a different module: Net::SMTPS. The following sample code sends a email message with an attachment.




use Net::SMTPS; 
         use MIME::Entity;

my $msg = MIME::Entity->build( 
Type => 'multipart/mixed',
    From => 'Some guy <someguy@callerip.ca>',
    To => 'anotherguy@callerip.ca',
    Subject => "My subject",
);
$msg->attach(
    Type     => 'application/pdf',
    Path     => "$file",
    Filename => "attachment.pdf",
    Encoding => 'base64'
);
# send the message
        my $smtp = Net::SMTPS->new("smtp.office365.com", Port => 587, doSSL => $ssl);
  $smtp->auth ( $user, $pass);

$smtp->mail($user);

$smtp->to( $to );
# Send the message and attachments
$smtp->data(  );
$smtp->datasend([ $msg->as_string ]);
$smtp->dataend;
$smtp->quit;

Saturday, 12 May 2018

Installing MCYRPT on a php::apache docker


Trying to install MCRYPT on a php:apache docker machine?

I found this to work:
RUN apt-get install -y libmcrypt-dev libreadline-dev
RUN pecl install mcrypt-1.0.1
RUN docker-php-ext-enable mcrypt

Sunday, 22 April 2018

Specifying multiple variables using node's asterisk-ami-client library




Big thank you to the authors of the asterisk-ami-client library, providing an easy hook into asterisk from node. I found that the asterisk-ami-client library restricted me to only one variable in a custom action. To specify multiple variables in an originate command I used the following:

  client.action({
            Action: 'Originate',
            ActionID: [id],
            Channel: 'SIP/PROVIDER/' + number,
            Context: [DialplanContext],
            Exten: [extension],
            Priority: '1',
            Variable: 'someVar=' + var1 + '\r\nVariable: someVar2=' + var2 + '\r\nVariable:someVar3=' + var4,            Async: 'yes'
        });


Tuesday, 23 January 2018

Windows 10 desktop icons flickering / flashing constantly with high Explorer CPU use

Like the title says... you have a Windows 10 machine (home or pro) and the desktop icons are all flickering or flashing like mad. Task Manager shows the explorer process (explorer.exe) using a high amount of processor (CPU) usage.

There are a number of things you can try, such as disabling or removing Norton and registry hacks etc.

A quick solution that I have seen work is simply to uninstall Adobe Reader DC. It was some sort of conflict with the Edge browser. In this client's case, they had an alternate PDF solution already so we did not look deeper into how to make Adobe Reader DC work in this case. There may be a solution for that but uninstalling is a good quick way to see if that is the problem area.

Monday, 25 December 2017

Sharing a user table in Loopback.io and Yii2

Problem


We wanted to implement Loopback.io as an API for our mobile app development, but needed it to play nice with our Yii2 web environment. We needed to be able to authenticate our Loopback / API users on the same user table that we authenticate our website users, using the same encrypted password.

Solution


This ended up being easier than I thought. Here are the steps that I followed:


  1. Create an AppUser class that inherits from User.
  2. Override the table that the AppUser class uses as its datastore.
  3. Create some Loopback fields in my user table.
  4. Tell AppUser to use the pre-existing primary key
  5. Turn off email validation

1. Create an AppUser Class to inherit from User

I took my cues from the documentation on how to make a class that extends User. Download the example referenced in the documentation to get the files. However, I called my class "AppUser" instead of "user", changing user.js and user.json to app-user.js and app-user.json.

I list my AppUser.json below. I left the AppUser.js as it was provided.

2. Override the table the ash AppUser class uses as its datastore.

By default, Loopback will try to use a table called AppUser to match the name of the class. In my example, I need it to reference the user table in the database, which my Yii2 application already uses. I used the documentation on this page. to figure out how to do this.

In the AppUser.json file, add the following section:

"options": {
    "mysql": {
      "table": "user"
    }
  },
Where user is the name of my table that I want the AppUser class to use as its datastore, instead of the default "AppUser" table.

3. Create some Loopback fields in my user table.

I added these columns, but perhaps I could have excluded them according to the documentation on this page.

ALTER TABLE `user` ADD `realm` varchar(512);
ALTER TABLE `user` ADD `emailVerified` tinyint(1);
ALTER TABLE `user` ADD  `verificationToken` varchar(512);

4. Tell AppUser to use the pre-existing primary key

I already had my own user_id column setup as the primary key. Loopback will try to use a column called id as the primary key by default. To prevent that, I set the field in the properties section with "id": "true" so that AppUser knows to use user_id as the primary key.

  "properties": {
    "user_id": {
      "type": "number",
      "id": true
    },
    "account_id": {
      "type": "number",
      "required": "true"
    }
  }

(I setup the account_id field as my Loopback app will need to reference that column. You would setup your other column/fields under properties)

I also set the idInjection section to false, so Loopback won't try and use the "id" field.

"idInjection": false,

5. Turn off email validation.

Insert the following in the AppUser.js file. "emailVerificationRequired": false,


Here is my entire AppUser.json file:

{
  "name": "AppUser",
  "base": "User",
  "idInjection": false,
  "restrictResetPasswordTokenScope": true,
  "emailVerificationRequired": false,
  "validations": [],
  "relations": {},
  "acls": [
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW",
      "property": "login"
    },
    {
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW",
      "property": "logout"
    },
    {
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW",
      "property": "findById"
    },
    {
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW",
      "property": "updateAttributes"
    }
  ],
  "methods": {},
  "options": {
    "mysql": {
      "table": "user"
    }
  },
  "properties": {
    "user_id": {
      "type": "number",
      "id": true
    },
    "account_id": {
      "type": "number",
      "required": "true"
    }
  }
}






Sunday, 17 December 2017

Loopback Mysql Error: Pool is Closed

Problem

You run node . to start your Loopback application; it starts fine, but on your first request to the API you get a database connection error:

{ Error: Pool is closed.    at Pool.getConnection (/home/ubuntu/code/lb3/node_modules/mysql/lib/Pool.js:25:15)    at MySQL.executeSQL (/home/ubuntu/code/cumberland/lb3/node_modules/loopback-connector-mysql/lib/mysql.js:239:12)    at /home/ubuntu/code/lb3/node_modules/loopback-connector-mysql/node_modules/loopback-connector/lib/sql.js:418:10

Shoot.

Solution

You could be disconnecting from the database in one of your startup scripts (under the boot directory). In my case, I had a script to create tables for Loopback's Role, User, AccessToken's etc and at the end I had the offending line:
module.exports = function(app)
{
  var mysqlDs = app.dataSources.mysqlDs;
  var lbTables = ['User', 'AccessToken', 'ACL', 'RoleMapping', 'Role'];
  mysqlDs.automigrate(lbTables, function(er) {
    if (er) throw er;
    console.log('Loopback tables [' - lbTables - '] created in ', mysqlDs.adapter.name);
    mysqlDs.disconnect();  });
}
I took out that line and all is well.

Sunday, 10 December 2017

Node.js connectivity fails connecting to AWS RDS

Problem:

You were able to connect to a local mysql instance with node.js (with the Loopback framework in my instance) but when you try to connect to an AWS RDS instance you get the dreaded Error: Handshake inactivity timeout  error.

And its not an issue with an older version of Node 4.2.

Solution:

You likely have a security group preventing your access to the RDS instance.

Don't worry, I felt like an idiot too; it passes.