Understanding #Closures in Javascript

May 19, 2018 Leave a comment

Understanding-JavaScript-Closure

Closures are quite an advanced feature of Javascript, but you really need to understand them whenever you need to do things like looping through asynchronous operations.

A typical use case is if you wanted to do many Ajax calls in a loop, and you find that the wrong variable value gets sent through, because by the time the Ajax returns the loop has already completed.

Here is a simplified example to demonstrate the problem, I’m using setTimeout instead of Ajax, to make the code more simple;

var arr = [1,2,3,4,5];

for(var i in arr)
{
setTimeout(function()
{
console.log(arr[i])
}, 500);
}

You may think, on first glance, that this code is going to create the output 1 2 3 4 5, but instead, it actually outputs 5 5 5 5 5 ? – here’s the solution:

for(var i in arr)
{
(function(i){
setTimeout(function()
{
console.log(arr[i])
}, 500)})(i);
}

Here, the setTimeout is wrapped in a (function(i){ … })(i) closure, which copies the value of i to the local scope of an inner function. so “i” inside the closure is of different scope to “i” in the for loop, and is in fact a different variable in memory.

 

 

Advertisements
Categories: Uncategorized

Common #SMTP Hosts and #SSL/TLS Settings

May 19, 2018 Leave a comment

smtpjs

A list of common SMTP servers and their SMTP Port and SSL settings from SMTPJS

Host Port Use SSL
smtp.gmail.com 25 TRUE
smtp.elasticemail.com 25 TRUE
smtp.gmail.com 465 TRUE
smtp25.elasticemail.com 25 TRUE
smtp.yourisp.com 25 TRUE
smtp.office365.com 25 TRUE
smtp.mail.ru 465 TRUE
smtp.elasticemail.com 2525 TRUE
smtp.laposte.net 25 TRUE
smtp.netcourrier.com 25 TRUE
smtp.mailgun.org 25 TRUE
smtp.gmail.com 587 TRUE
smtp-mail.outlook.com 25 TRUE
smtp.technitronique.fr 465 TRUE
smtp.naver.com 25 TRUE
gator3109.hostgator.com 25 TRUE
smtp.qq.com 25 TRUE
smtp.mail.ru 25 TRUE
smtp.develmail.com 465 TRUE
smtp.googlemail.com 25 TRUE
smtp.sendgrid.net 25 TRUE
ssl0.ovh.net 993 TRUE
mail.smtp2go.com 465 TRUE
smtp.mail.yahoo.com 25 TRUE
smtps.aruba.it 465 TRUE
smtp.zoho.com 25 TRUE
smtp.zoho.com 465 TRUE
smtp.live.com 25 TRUE
smtp.google.com 25 TRUE
mail.smtp2go.com 25 TRUE
mail.brideschool.pt 465 TRUE
in-v3.mailjet.com 25 TRUE
smtp.163.com 465 TRUE
smtpout.secureserver.net 25 TRUE
smtp.office365.com 587 TRUE
smtp.gmail.com 465 FALSE
mail.allpapropiedades.cl 465 TRUE
email-smtp.us-east-1.amazonaws.com 465 TRUE
smtp.163.com 25 TRUE
smtp.elasticemail.com:2525 25 TRUE
mail.andreitg.com 465 TRUE
smtp.yandex.ru 25 TRUE
smtp.yandex.ru 465 TRUE
smtp.strato.de 25 TRUE
smtp.web.de 25 TRUE
mail.intersistemi.it 25 TRUE
smtp.gmail.com 25 FALSE
mail.soundsbysunday.com 465 TRUE
mail.tessabarlin.co.za 465 TRUE
smtp.creditogs.com.ar 25 TRUE
Categories: Uncategorized

#SQL Hashbytes compatible code in C#

May 18, 2018 Leave a comment

dog1

The SQL function hashbytes allows you to hash strings directly in the database; by using something such as;

select hashbytes(‘MD5′,’hello world’)

which returns 0x5EB63BBBE01EEED093CB22BB8F5ACDC3

But if you want to compare this string with a hash created on the server by C#, then you’ll need to get it into the right format – where you could use this code here:

public static string HashBytes(string valueToHash)
{
HashAlgorithm hasher = new MD5CryptoServiceProvider();
Byte[] valueToHashAsByte = Encoding.UTF8.GetBytes(String.Concat(valueToHash, SaltValue));
Byte[] returnBytes = hasher.ComputeHash(valueToHashAsByte);
StringBuilder hex = new StringBuilder(returnBytes.Length * 2);
foreach (byte b in returnBytes) hex.AppendFormat(“{0:x2}”, b);
return “0x” + hex.ToString().ToUpper();
}

Categories: Uncategorized

Helo command rejected: need fully-qualified hostname

May 17, 2018 Leave a comment

smtpjs

When sending email from C#, if you ever get the error “Helo command rejected: need fully-qualified hostname”, you may end up scratching your head, because there is no easy way to change what gets sent in the HELO command from the SMTPClient class.

You, can however, use reflection to override what the SmtpClient class sends. here I have hard-coded “www.smtpjs.com”  – because this code is specifically for this project.

You need to subclass SMTPClient as SMTPClientEx, and override the private properties localHostName and clientDomain as follows;

using System.Net.Mail;
using System.Reflection;

/// <inheritdoc />
/// <summary>
/// Subclass of Smtpclient, with overridden HELO
/// </summary>
public class SmtpClientEx : SmtpClient
{

public SmtpClientEx()
{
Initialize();
}

private void Initialize()
{
const string strHelo = “www.smtpjs.com”;
var tSmtpClient = typeof(SmtpClient);
var localHostName = tSmtpClient.GetField(“localHostName”, BindingFlags.Instance | BindingFlags.NonPublic);
if (localHostName != null) localHostName.SetValue(this,strHelo);
var clientName = tSmtpClient.GetField(“clientDomain”, BindingFlags.Instance | BindingFlags.NonPublic);
if (clientName != null) clientName.SetValue(this, strHelo);
}
}

Categories: Uncategorized

Automate “Get Latest Version” from Visual Studio Team Services #VSTS

May 11, 2018 Leave a comment

VS-TFS

If you use Visual Studio Team Services – previously known as “Visual Studio Online” to manage your source control, and you find yourself frequently exporting zip files, and copying them to deployment, you might be pleased to know there is an extensive API that allows you do a “Get Latest Version” from C#

So, first off you need to create an app with VSTS here;

https://app.vsaex.visualstudio.com/app/register

You’ll need to have a publicly accessible HTTPS website for the callback. I’ve just used https://<mydomain>/callback.aspx – I selected all the available scopes, but you can be more selective.

Once registered, you’ll get your Oauth credentials, and slot them into your web.config

<appSettings>
<add key=”app_id” value=”….”/>
<add key=”app_secret” value=”….”/>
<add key=”client_secret” value=”…..”/>
<add key=”Authorize_URL” value=”https://app.vssps.visualstudio.com/oauth2/authorize?mkt=en-US”/&gt;
<add key=”Access_Token_URL” value=”https://app.vssps.visualstudio.com/oauth2/token?mkt=en-US”/&gt;
<add key=”Scopes” value=”vso.build_execute vso.code_full vso.code_status vso.codesearch vso.connected_server vso.dashboards vso.dashboards_manage vso.entitlements vso.extension.data_write vso.extension_manage vso.gallery_acquire vso.gallery_manage vso.graph_manage vso.identity_manage vso.loadtest_write vso.machinegroup_manage vso.memberentitlementmanagement_write vso.notification_diagnostics vso.notification_manage vso.packaging_manage vso.profile_write vso.project_manage vso.release_manage vso.security_manage vso.serviceendpoint_manage vso.symbols_manage vso.taskgroups_manage vso.test_write vso.wiki_write vso.work_full vso.workitemsearch”/>
<add key=”RemoteLogCat” value=”…..”></add>
<add key=”RemoteScope” value=”$/….”></add>
<add key=”LocalWorkSpace” value=”F:\….\”></add>
<add key=”accountName” value=”…..”></add>
<add key=”projectName” value=”…..”></add>
</appSettings>

I’ve removed sensitive data above, but each setting is as follows:

  • app_id, app_secret, client_secret – Displated after creating your app on VSTS
  • RemoteLogCat – optional, from RemoteLogCat.com
  • RemoteScope – The path where the root of your website resides on TFS
  • LocalWorkSpace – The file path where the website will be downloaded to locally
  • accountName – your account on VSTS
  • projectName – the project within your account on VSTS

Then, the first step is to request consent to access your account on VSTS, which you can do a redirect link as follows;

strUrl += “?client_id=” + ConfigurationManager.AppSettings[“app_id”];
strUrl += “&response_type=Assertion”;
strUrl += “&state=any”;
strUrl += “&scope=” + ConfigurationManager.AppSettings[“Scopes”];
strUrl += “&redirect_uri=https://…./callback.aspx”;
Response.Redirect(strUrl);
This, should display a page such as the following;
login
… Press Accept at the foot of the page, and you are reditected to your callback, with some parameters in the Querystring.
To Convert the code to a bearer token, you have to send this back to VSTS as follows;
var strCode = Request.QueryString[“code”];
var strClientSecret = ConfigurationManager.AppSettings[“client_secret”];
var strCallbackUrl = “https://&#8230;./callback.aspx”;
var strPostData = GenerateRequestPostData(strClientSecret, strCode, strCallbackUrl);
var wc = new WebClient();
wc.Headers[“Content-Type”] = “application/x-www-form-urlencoded”;
try
{
var strJson = wc.UploadString(strTokenUrl, strPostData);
Response.Write(strJson);
Response.Write(“<hr>”);
var jObject = JObject.Parse(strJson);
var strAccessCode = jObject[“access_token”].ToString();
//BuildLocalWorkSpaceTree(strAccessCode);
//GetLastChangeSet(strAccessCode);
}
catch(WebException ex){
var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
Response.Write(resp);
}
Where the function GenerateRequestPostData is defined as follows;
privatestaticstring GenerateRequestPostData(string appSecret, string authCode, string callbackUrl)
{
return String.Format(
“client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}”,
HttpUtility.UrlEncode(appSecret),
HttpUtility.UrlEncode(authCode),
callbackUrl
);
}
If you run this, you should see some JSON on the page, with your bearer token.
Now, to do something useful with the code, let’s imagine, you want to Do a “Get Latest Version”, then you can uncomment the BuildLocalWorkSpaceTree , and add the function
privatevoid BuildLocalWorkSpaceTree(string bearer)
{
var strLocalWorkspace = ConfigurationManager.AppSettings[“LocalWorkSpace”];
var strAccountName = ConfigurationManager.AppSettings[“accountName”];
var strRemoteScope = ConfigurationManager.AppSettings[“RemoteScope”];
DeleteAllFilesAndFoldersInPath(strLocalWorkspace);
var strItemsUrl = “https://{0}.visualstudio.com/_apis/tfvc/items?scopePath={1}&recursionLevel=Full&api-version=5.0-preview.1”;
strItemsUrl = string.Format(strItemsUrl, strAccountName, strRemoteScope);
var wc = new WebClient();
wc.Headers[“Authorization”] = “Bearer ” + bearer;
var strItemsJson = wc.DownloadString(strItemsUrl);
Response.Write(“<hr>”);
var jObject = JObject.Parse(strItemsJson);
foreach (var jItem in jObject[“value”])
{
var strRemotePath = jItem[“path”].ToString();
var strLocalPath = strRemotePath.Replace(strRemoteScope, strLocalWorkspace).Replace(“/”, @”\”);
Response.Write(“Creating ” + strLocalPath + “<br>”);
Response.Flush();
if (jItem[“isFolder”] != null)
{
Directory.CreateDirectory(strLocalPath);
}
else
{
var strItemUrl = “https://{0}.visualstudio.com/_apis/tfvc/items?download=true&path={1}&api-version=5.0-preview.1”;
strItemUrl = string.Format(strItemUrl, strAccountName, HttpUtility.UrlEncode(strRemotePath));
var raw = wc.DownloadData(strItemUrl);
File.WriteAllBytes(strLocalPath,raw);
}
}
}
Categories: Uncategorized

Remote #ErrorLogging in C#

May 11, 2018 Leave a comment

rlc

If you are running a C# Application on a client’s machine, and can’t run the debugger on it, then instead of asking your client to send you log files whenever something goes wrong, you can use a remote logging service to record error events, and view them, and even act on them before the client complains.

This example uses RemoteLogCat.com – a logging service designed for Android, but works equally well in C# / .NET. You will need to have an API Key, and store it as a setting as “RemoteLogCat” in your web.config / app.config

public class Logging
{
public static string key = ConfigurationManager.AppSettings[“RemoteLogCat”];
    public static void Log(string channel, string log)
{
var strUrl = “http://www.remotelogcat.com/log.php?apikey={0}&channel={1}&log={2}”;
strUrl = string.Format(strUrl, key, channel, log);
var wc = new WebClient();
wc.DownloadString(strUrl);
}
}
This is then called using
Logging.Log(“MyApp”,”Your Error”)
Categories: Uncategorized

#ImageRecognition #API with REST webservice

May 10, 2018 Leave a comment

ai

Image Recognition API

This Image Recognition API allows images to be tagged with a label to describe the content of the image, and a confidence score percentage to indicate the level of trust in the algorithm’s judgement. View our homepage at http://imagerecognition.apixml.net

Image Recognition Web Service

The API endpoint can be accessed via this url:

http://imagerecognition.apixml.net/api.asmx

It requires an API Key, which can be applied for via this url:

https://goo.gl/7ND8jG

Recognise

The first API endpoint is http://imagerecognition.apixml.net/api.asmx?op=Recognise

It accepts a url to an image, for example “https://www.argospetinsurance.co.uk/assets/uploads/2017/12/cat-pet-animal-domestic-104827-1024×680.jpeg

And returns a result as follows;

<RecogntionResult xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://imagerecognition.apixml.net/”&gt;

<Label>Egyptian cat</Label>

<Confidence>3.63228369</Confidence>

</RecogntionResult>

Urls must be publicly accessible, you cannot use localhost urls, or intranet addresses.

RecogniseFromBase64

The next API Endpoint is http://imagerecognition.apixml.net/api.asmx?op=RecogniseFromBase64

It accepts a base64 encoded string containing the image, you must also provide the image format, such as “jpg”, “png”, “bmp” etc.

It returns a result as follows;

<RecogntionResult xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://imagerecognition.apixml.net/”&gt;

<Label>Egyptian cat</Label>

<Confidence>3.63228369</Confidence>

</RecogntionResult>

OCR Web Service

Optical character recognition converts an image containing text to the text itself, a microsite for this service can be reviewed at http://ocr.apixml.net/ , here, there are two API endpoints exposed

ProcessUrl

Extract text from an image that is available on the internet via a Url. It’s endpoint is here

http://ocr.apixml.net/ocr.asmx?op=ProcessUrl

Urls must be publicly accessible, you cannot use localhost urls, or intranet addresses.

ProcessBase64

Extract text from an image which has been base64 encoded. You also require a file extension (png/jpg/etc) to indicate the format. It’s endpoint is here;

http://ocr.apixml.net/ocr.asmx?op=ProcessBase64

By default, this service will assume a single line of text, rather than a page of text, in order to change this default behavior, or to customise it to your needs, then you can use the “extraArguments” parameter to fine-tune the OCR operation. The full list of these possible parameters are available on http://ocr.apixml.net/

RESOURCES

Contact information

This software is designed by Infinite Loop Development Ltd (http://www.infiniteloop.ie) and is subject to change. If you would like assistance with custom software development work, please contact us below;

  • info@infiniteloop.ie

  • +44 28 71226151

  • Twitter: @webtropy

Categories: Uncategorized