How to send money via Wise

Hello. In this article, I am going to show you, how you can send money to someone via Wise.

What is Wise ?

Wise is a foriegn exchange company that allows people all around the world to send money to their friends or family members. Most of our clients use Wise for buying our premium projects.

Table of contents – Send money via Wise

  1. Visit wise.com
  2. Enter amount to send
  3. Login or sign up
  4. Double check amount and currency
  5. Select recipient
  6. Enter account details
  7. Place of birth
  8. Reason for transfer
  9. Review transfer details
  10. Select payment method
  11. Pay with card
  12. Verification code
  13. Track money
  14. Money is being processed by Wise
  15. Money received
  16. Transfer complete

How to send money using Wise ?

Following are the simple steps that you can follow to send money.

Step 1: Visit wise.com

Visit wise.com in your favorite browser.

1. Visit wise.com - send money via wise
Visit wise.com

Step 2: Enter amount to send

Click on “Send money now” button and you will be redirected to a page where you can enter the amount to send. You need to select the currency from where you will be sending money. You are also required to select the recipient’s currency.

2. Enter amount to send
Enter amount to send

Step 3: Login or Sign up

After selecting the currencies and entering the amount, click the “Get started” button and you will be redirected to login page. Create an account if you do not already have one, otherwise, simply login. You can also do login via Google, Facebook or Apple.

Login or sign up
Login or sign up

Step 4: Double check amount and currency

After login, you will be redirected to the following screen. You can double check the amount you are sending and the currency.

4. Double check amount and currency - send money via wise
Double check amount and currency

Step 5: Select recipient

Then, select either you are sending the money to yourself or to someone else.

5. Select recipient
Select recipient

Step 6: Enter account details

Enter the bank account details of the recipient.

6. Enter account details
Enter account details

Step 7: Place of birth

Sometimes, Wise asks to enter the place of birth of the recipient, just for the confirmation that you are sending money to someone you know.

7. Place of birth of recipient
Place of birth of recipient

Step 8: Reason for transfer

Then you need to select the reason for transfer. Most of my clients select “Tuition fee or study expenses” while making payments because “Digital products” option is not yet available at Wise.

8. Reason for transfer - send money via wise
Reason for transfer

Step 9: Review details of transfer

After that, a page will open from where you can review the details of your transfer. It includes the amount you are sending and the recipient’s bank account details.

9. Review details of transfer
Review details of transfer

Step 10: Select payment method

Select your preferred payment method.

Tip: Most of our clients use “Credit card” option.

10. Select payment method
Select payment method

Step 11: Pay with card

If you wish to pay with your card, you simply need to enter your card details.

11. Pay with card - send money via wise
Pay with card

Step 12: Verification code

Sometimes, wise.com sends a verification code to your phone number via SMS for verification.

12. Verification code
Verification code

13. Track money

Once verified, the process is complete. Now sit back, relax and track your payment.

13. Track money
Track money

Step 14: Money is being processed by wise

Your money will be processed by wise.com. This step might take 10-15 minutes approximately.

14. Money is being processed by wise - send money via wise
Money is being processed by wise

15. Money received

Recipient will receive the money once the payment is processed.

15. Money received
Money received

16. Transfer complete

Now your transfer is complete and your recipient should have received the money in his bank account.

16. Transfer complete - send money via wise
Transfer complete

If you face any problem in following this, kindly do let me know.

How to call Node JS function from EJS

In this tutorial, you will learn how to call a function in your Node JS server file from the EJS template file.

First, we are going to install all the required modules. Run the following commands in your terminal:

1
2
3
> npm install http express ejs
> npm install -g nodemon
> nodemon server.js

Then, create a file named server.js and write the following code in it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const app = require("express")()
const http = require("http").createServer(app)
const ejs = require("ejs")
app.set("view engine", "ejs")
 
const port = process.env.PORT || 3000
http.listen(port, function () {
    app.get("/", async function (request, result) {
        const html = await ejs.renderFile("views/index.ejs", null, {
            async: true
        })
 
        result.send(html)
        return
    })
})

Then, create a folder named views and inside this folder, create a file named index.ejs

To call a function from EJS file, we will first create a helper module in our server file. Create a file named helper.js at the root of your project. Following code will go in this file:

1
2
3
4
5
module.exports = {
    myFunc() {
        return "My function value."
    }
}

Then, include this module in your server.js file.

1
const helper = require("./helper")

And pass it in your renderFile function like this:

1
2
3
4
5
const html = await ejs.renderFile("views/index.ejs", {
    helper: helper
}, {
    async: true
})

Now you can easily call it from your index.ejs in the following way:

1
<%= helper.myFunc() %>

Since you are rendering the EJS file using await command, if you have to include another EJS file, you have to include it using await as well.

1
<%- await include ("header") %>

So that’s how you can call function in Node JS server file from your EJS template file. If you face any problem in following this, kindly do let me know.

Securely upload and view image in Node JS and Mongo DB

Learn how to securely upload and view image in Node JS and Mongo DB. Most of the time when we create a website where we allow users to upload images, we face a problem to secure them from unauthorized access. For example, you are creating a website where you are allowing users to upload pictures and share them with only selected people. Now you do not want any other person to view that picture.

This can be done easily with Node JS. First, we are going to create an empty project. So run the following commands in your terminal.

1
2
3
4
> npm init
> npm install express express-formidable ejs fs mongodb
> npm install -g nodemon
> nodemon server.js

Upload image

After that, create a file named server.js and write the following code in it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// server.js
 
const express = require("express")
const app = express()
app.set("view engine", "ejs")
 
const port = process.env.PORT || 3000
app.listen(port, function () {
    console.log("Server started.")
 
    app.get("/", function (request, result) {
      result.render("index")
    })
})

Now, we will create a folder named views and inside this folder, create a file named index.ejs. Following will be the content of this file.

1
2
3
4
5
6
<!-- views/index.ejs -->
 
<form method="POST" action="/upload" enctype="multipart/form-data">
  <input type="file" name="file" />
  <input type="submit" value="Upload" />
</form>

This will create a form where user can select image. You can access this from the URL:

1
http://localhost:3000

Now in our server.js file, we will include the file system module, express formidable module and connect Mongo DB.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// server.js
 
const fs = require("fs")
const mongodb = require("mongodb")
const ObjectId = mongodb.ObjectId
const mongoClient = new mongodb.MongoClient("mongodb://localhost:27017")
 
const expressFormidable = require("express-formidable")
app.use(expressFormidable())
 
// Connect the client to the server (optional starting in v4.7)
await mongoClient.connect()
 
// Establish and verify connection
const db = await mongoClient.db("upload_view")
db.command({ ping: 1 })
console.log("Database connected")

After that, we will create a route that will handle this request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// server.js
 
app.post("/upload", async function (request, result) {
  const file = request.files.file
 
  const fileData = await fs.readFileSync(file.path)
  if (!fileData) {
    console.error(fileData)
    return
  }
 
  const filePath = "uploads/" + (new Date().getTime()) + "-" + file.name
  fs.writeFileSync(filePath, fileData)
 
  await db.collection("files").insertOne({
    path: filePath,
    name: file.name,
    size: file.size
  })
 
  result.send("File has been uploaded.")
})

This will upload the file in your uploads folder. If you do not have that folder, you need to create it. This will also save the uploaded file data in Mongo DB.

You will not be able to view the images directly from the URL in the browser. So we need to create an API allowing users to view the image.

View image

First, we will fetch all the images from Mongo DB. So change your main route to the following:

1
2
3
4
5
6
7
8
// server.js
 
app.get("/", async function (request, result) {
  const files = await db.collection("files").find({}).toArray()
  result.render("index", {
    files: files
  })
})

Now, in your views/index.ejs, we will loop through all images and display their name and a link to view.

1
2
3
4
5
6
7
8
9
10
11
<!-- views/index.ejs -->
 
<% files.forEach(function (file) { %>
  <p>
    <a href="image/<%= file._id %>">
      <%= file.name %>
    </a>
 
    <img src="image/<%= file._id %>" style="width: 300px;" />
  </p>
<% }) %>

Finally, we need to create an API that will return the content of image. This will allow you to view the image on user side.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// server.js
 
app.get("/image/:_id", async function (request, result) {
  const _id = request.params._id
  const file = await db.collection("files").findOne({
    _id: new ObjectId(_id)
  })
 
  if (file == null) {
    result.json({
      status: "error",
      message: "File not found."
    })
    return
  }
 
  const fileData = await fs.readFileSync(file.path)
  if (!fileData) {
    console.error(fileData)
    return
  }
  result.writeHead(200, {
    "Content-Type": "image/png",
    "Content-Length": fileData.length
  })
  result.end(fileData)
})

Now you will be able to view the image as well.

Convert datetime to local timezone – Javascript, PHP and MySQL

In this article, you will learn how to convert UTC datetime to user’s local timezone using Javascript.

Your database is centralized, but your user’s are located on different geolocations. Time stored in your database is usually UTC by default. But your users should see the time according to their timezone. So how are you going to do it ?

Table of contents:

  1. Save datetime in UTC
  2. Get user’s local timezone
  3. Convert UTC to timezone

Save datetime in UTC

First, we will create a users table. Run the following query in your phpMyAdmin.

1
2
3
4
5
CREATE TABLE IF NOT EXISTS users(
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name TEXT,
    created_at DATETIME
)

Then we will insert a row in this table.

1
INSERT INTO users(name, created_at) VALUES ('Adnan', UTC_TIMESTAMP())

Note that we are using UTC_TIMESTAMP() MySQL built-in function. This will return the current UTC date and time.

Get user’s local timezone

To get the user’s local timezone, we will use the Intl object of Javascript. It stands for internationalization.

1
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone

DateTimeFormat() creates a new DateTimeFormat object.

resolvedOptions() will return a new object. Its object’s properties reflects the locale and datetime format sets during the initialization of Intl.DateTimeFormat() object.

timeZone will return the timezone of user’s local computer.

We saved it in a variable. Now we will call an AJAX request to fetch the records from database using PHP.

1
2
3
4
5
6
7
8
9
10
11
12
13
const ajax = new XMLHttpRequest()
ajax.open("POST", "get-data.php", true)
 
ajax.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log(this.responseText)
    }
}
 
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
const formData = new FormData()
formData.append("time_zone", timeZone)
ajax.send()

This will call an AJAX request and attach the timezone value with the request.

Convert UTC datetime to local timezone

To convert the UTC value from database to user’s local timezone, first we need to get the value of user’s timezone from the AJAX request. So create a file named get-data.php and inside this file, creates a connection with the MySQL database.

1
2
3
<?php
 
$conn = new PDO("mysql:host=localhost;dbname=your_db_name", "db_user", "db_password");

Then we will get the timezone from AJAX request and fetch the single user’s record.

1
2
3
4
5
6
7
8
9
10
$time_zone = $_POST["time_zone"] ?? "";
if (!empty($time_zone))
{
    date_default_timezone_set($time_zone);
}
 
$sql = "SELECT * FROM users";
$result = $conn->prepare($sql);
$result->execute([]);
$user = $result->fetchObject();

Finally, we will convert the timestamp from UTC to user’s local timezone and return it to the client.

1
echo date("d M, Y h:i:s a", strtotime($user->created_at . " UTC"));

If you open your browser’s console tab, you will see the date and time but in your own timezone.

Using DateTimeZone class

Calling date_default_timezone_set() will set the entire request’s timezone to the user timezone. If you want to convert only one column’s value to user’s local timezone, you can use PHP built-in DateTimeZone class.

First, you need to create its object:

1
$dateTimeZone = new DateTimeZone($time_zone);

Then, you can create a datetime object from timestamp stored in MySQL database and set it to use the timezone of user.

1
2
$dateTime = new DateTime($user->created_at);
$dateTime->setTimezone($dateTimeZone);

Finally, we can display the date and time in the format.

1
echo $dateTime->format("d M, Y h:i:s a");

That’s how you can convert UTC datetime to user’s local timezone using Javascript.

Video buffering and streaming in NodeJS

In this tutorial, we are going to teach you, how you can create video streaming and buffering like YouTube in NodeJS. In YouTube, you have noticed that the whole video is not downloaded in the browser at once. Only 10-15 seconds of the video has been downloaded in the browser. And more will be downloaded as user continues to watch.

Same technique it applied by Netflix where you watch just the 10-15 seconds of video and the next 10 seconds are fetched as you watch. This technique is useful in 2 terms:

  1. First, it provides a layer of security. You do not write the direct path of video in the <video> tag. You write the API route, and the API will fetch the video data.
  2. Second, it saves bandwidth. If a file is of 100 MB in size, user can download just 1 MB of at start. User can start watching the 1 MB and the next MBs will automatically gets downloaded periodically. User does not have to wait for whole 100 MBs to get downloaded.

Let’s get started

Start by creating an empty folder in your computer. Make sure you have NodeJS installed in your system. Open command prompt or terminal in that folder and run the following command in it:

1
> npm install express fs ejs

express module is used for routing. fs stands for File System, this module will be used to read the video file. ejs is a templating engine that will be used to render the HTML file. We will display the video in a <video> tag in an HTML file.

Once you ran the above commands, create a file named server.js. This is where we will do all the streaming and buffering work. Write the following code in that file:

1
2
3
4
5
6
7
8
9
10
11
12
const app = require("express")()
const fs = require("fs")
 
app.set("view engine", "ejs")
 
app.get("/", function (request, result) {
  result.render("video");
})
 
app.listen(3000, function () {
  console.log("Server started.")
})

Save the file and run the URL: http://localhost:3000 in the browser. You might see an error that the file video.ejs in not found in the views folder. You need to create a folder named views and inside this folder, create a file named video.ejs.

Following will be the code of views/video.ejs file.

1
2
3
<video id="videoPlayer" width="650" controls>
    <source src="http://localhost:3000/video" type="video/mp4" />
</video>

You can see that we have not set the direct path of the video. Instead we wrote the path of our API endpoint that will return the video data.

Buffer the video

Now we need to create an API endpoint that will handle this request. Create the following GET route in your server.js file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
app.get("/video", function (req, res) {
  // Ensure there is a range given for the video
  const range = req.headers.range
  if (!range) {
    res.status(400).send("Requires Range header")
  }
 
  // get video stats (about 100MB)
  const videoPath = "video.mp4"
  const videoSize = fs.statSync(videoPath).size
 
  // Parse Range
  // Example: "bytes=32324-"
  const CHUNK_SIZE = 10 ** 6 // 1MB
  const start = Number(range.replace(/\D/g, ""))
  const end = Math.min(start + CHUNK_SIZE, videoSize - 1)
 
  // Create headers
  const contentLength = end - start + 1
  const headers = {
    "Content-Range": `bytes ${start}-${end}/${videoSize}`,
    "Accept-Ranges": "bytes",
    "Content-Length": contentLength,
    "Content-Type": "video/mp4",
  }
 
  // HTTP Status 206 for Partial Content
  res.writeHead(206, headers)
 
  // create video read stream for this particular chunk
  const videoStream = fs.createReadStream(videoPath, { start, end })
 
  // Stream the video chunk to the client
  videoStream.pipe(res)
})

** operator is used to raise the first operand to the power of second operand. That’s how you can create a video streaming and buffering engine in NodeJS. Comments has been added with each line for explanation. If you refresh the page now, you will start seeing the video with buffer on it. If you face any problem in following this, kindly do let me know.

End-to-end encryption in Javascript, PHP and MySQL

End-to-end encrypted chats are more secured than the ones where encryption is done on the server side. Because the messages get encrypted even before sending them to the server. This will prevent any read or alter operation of messages in-transit. Let’s learn how to do it.

We will be using Javascript for encryption and decryption. And we will be using PHP for handling AJAX requests. All the encrypted messages will be stored in MySQL database.

Table of contents

  1. Setup database
  2. Private and public keys
  3. Encrypt message
  4. Decrypt message

Setup database

First, open your phpMyAdmin and create a database named end_to_end_encryption. Then create a file named db.php and write the following code in it.

1
2
3
<?php
 
$conn = new PDO("mysql:host=localhost;dbname=end_to_end_encryption", "root", "");

The second and third parameters are username and password to the database. You can change them as per your server. Then we will create a file named index.php and write the following code in it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
 
require_once "db.php";
 
$sql = "CREATE TABLE IF NOT EXISTS users(
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(255) NOT NULL,
  privateKey TEXT DEFAULT NULL,
  publicKey TEXT DEFAULT NULL
)";
$conn->prepare($sql)->execute();
 
$sql = "CREATE TABLE IF NOT EXISTS messages(
  id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
  sender VARCHAR(255) NOT NULL,
  receiver VARCHAR(255) NOT NULL,
  message TEXT NOT NULL,
  iv TEXT NOT NULL
)";
$conn->prepare($sql)->execute();
 
?>

This will create 2 tables. One for users where we will store each user’s private and public key. Second table where we will store all our encrypted messages. We will also store IV (initialization vector) required for decrypting the message. The IV will also be encrypted. Run the following URL in the browser.

1
http://localhost/end-to-end-encryption-js-php-mysql/index.php

You need to insert 2 users manually in the user’s table to properly understand the mechanism of end-to-end encryption.

We assume that you have a folder named end-to-end-encryption-js-php-mysql where you placed your index.php file. After running the above URL in the browser, you need to check your phpMyAdmin. You will now see your 2 tables created.

Private and public keys

Private and public keys of each user is unique and it is used to encrypt and decrypt the messages. We will encrypt the message using sender’s private key with receiver’s public key. Similarly, we will decrypt the message using logged-in user’s private and other user’s public key. So we will create a form in our index.php file.

1
2
3
4
<form onsubmit="doLogin(this)">
  <input type="email" name="email" id="email" placeholder="Enter email" />
  <input type="submit" value="Login" />
</form>

You need to perform the function below in your own login module. We are not going into the authentication because that is not in the scope of this tutorial. When the form submits, we will call an AJAX request to authenticate the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
  function doLogin() {
    event.preventDefault()
     
    const form = event.target
    const formData = new FormData(form)
     
    const ajax = new XMLHttpRequest()
    ajax.open("POST", "login.php", true)
    ajax.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        if (!this.responseText) {
          updateKeys()
        }
      }
    }
 
    ajax.send(formData)
  }
</script>

Create a file named login.php that will tell if the logged-in user has private and public keys.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
 
require_once "db.php";
$email = $_POST["email"];
 
$sql = "SELECT publicKey FROM users WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $email
]);
$user = $result->fetchObject();
 
echo ($user && $user->publicKey != null);
exit();

This will return true or false indicating if the user has public key in the database. If not, then the client side will call another AJAX request from the function updateKeys() to generate the keys and save them in database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
async function updateKeys() {
      const keyPair = await window.crypto.subtle.generateKey(
          {
              name: "ECDH",
              namedCurve: "P-256",
          },
          true,
          ["deriveKey", "deriveBits"]
      )
 
      const publicKeyJwk = await window.crypto.subtle.exportKey(
          "jwk",
          keyPair.publicKey
      )
 
      const privateKeyJwk = await window.crypto.subtle.exportKey(
          "jwk",
          keyPair.privateKey
      )
 
      const formData = new FormData()
      formData.append("email", document.getElementById("email").value)
      formData.append("publicKey", JSON.stringify(publicKeyJwk))
      formData.append("privateKey", JSON.stringify(privateKeyJwk))
 
      const ajax = new XMLHttpRequest()
      ajax.open("POST", "update-keys.php", true)
      ajax.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
          console.log(this.responseText)
        }
      }
 
      ajax.send(formData)
}

We are using P-256 curve algorithm to generate a key pair. Then we are exporting private and public keys JWK (JSON Web Token). To save them in database, we are converting them to JSON string. Now we need to create a file named update-keys.php that will update those keys in user’s table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
require_once "db.php";
 
$email = $_POST["email"];
$publicKey = $_POST["publicKey"];
$privateKey = $_POST["privateKey"];
 
$sql = "UPDATE users SET publicKey = ?, privateKey = ? WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $publicKey,
  $privateKey,
  $email
]);
 
echo "Updated";
exit();

Try running the index.php file again. Enter any of the user’s email address from database and hit “Login”. You will see the message “Updated” in the browser console. But you will see it just once, because once the public keys are updated, this function won’t gets called. If you check your phpMyAdmin, you will see that the private and public key of that user will be updated. You should do that for both users so each user will have its own private and public keys.

Encrypt message

Now that each user has its own private and public keys, we can use them to encrypt messages and save them in database. Create a file named send.php that will display a form to enter sender and receiver’s email addresses and a message to encrypt.

1
2
3
4
5
6
<form onsubmit="sendMessage()" id="form-message">
  <input type="email" name="sender" placeholder="Sender email" />
  <input type="email" name="receiver" placeholder="Receiver email" />
  <textarea name="message" placeholder="Message"></textarea>
  <input type="submit" value="Send" />
</form>

We will create 2 Javascript variables that will hold the sender’s private key and receiver’s public key values.

1
2
3
4
<script>
  let publicKey = ""
  let privateKey = ""
</script>

We are using let because these values will be updated later. Create a function that will be called when the above form submits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function sendMessage() {
  event.preventDefault()
 
  if (publicKey == "" || privateKey == "") {
    const form = event.target
    const formData = new FormData(form)
     
    const ajax = new XMLHttpRequest()
    ajax.open("POST", "get-keys.php", true)
    ajax.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        const response = JSON.parse(this.responseText)
        privateKey = JSON.parse(response[0])
        publicKey = JSON.parse(response[1])
        doSendMessage()
      }
    }
 
    ajax.send(formData)
  } else {
    doSendMessage()
  }
}

This will first check if the private and public keys are already fetched. If fetched, then it will call doSendMessage() function that we will create later. If not fetched, then we will first fetch the keys and then call the 2nd function. We are using this check because if you are sending multiple messages to the same recipient, then it should not get private and public keys on each send message request.

Now we will create a file named get-keys.php to fetch the sender’s private key and receiver’s public key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
 
require_once "db.php";
 
$sender = $_POST["sender"];
$receiver = $_POST["receiver"];
 
$sql = "SELECT privateKey FROM users WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $sender
]);
$userSender = $result->fetchObject();
 
$sql = "SELECT publicKey FROM users WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $receiver
]);
$userReceiver = $result->fetchObject();
 
echo json_encode([
  $userSender->privateKey,
  $userReceiver->publicKey
]);
exit();

When the keys are returned on the client side, the variables will be updated and the second function will be called to send the message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
async function doSendMessage() {
      const form = document.getElementById("form-message")
      const formData = new FormData()
      formData.append("sender", form.sender.value)
      formData.append("receiver", form.receiver.value)
 
      const publicKeyObj = await window.crypto.subtle.importKey(
          "jwk",
          publicKey,
          {
              name: "ECDH",
              namedCurve: "P-256",
          },
          true,
          []
      )
 
      const privateKeyObj = await window.crypto.subtle.importKey(
          "jwk",
          privateKey,
          {
              name: "ECDH",
              namedCurve: "P-256",
          },
          true,
          ["deriveKey", "deriveBits"]
      )
 
      const derivedKey = await window.crypto.subtle.deriveKey(
          { name: "ECDH", public: publicKeyObj },
          privateKeyObj,
          { name: "AES-GCM", length: 256 },
          true,
          ["encrypt", "decrypt"]
      )
 
      const encodedText = new TextEncoder().encode(form.message.value)
      const iv = new TextEncoder().encode(new Date().getTime())
      const encryptedData = await window.crypto.subtle.encrypt(
          { name: "AES-GCM", iv: iv },
          derivedKey,
          encodedText
      )
      const uintArray = new Uint8Array(encryptedData)
      const string = String.fromCharCode.apply(null, uintArray)
      const base64Data = btoa(string)
      const b64encodedIv = btoa(new TextDecoder("utf8").decode(iv))
 
      formData.append("message", base64Data)
      formData.append("iv", b64encodedIv)
   
      const ajax = new XMLHttpRequest()
      ajax.open("POST", "send-message.php", true)
      ajax.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
          console.log(this.responseText)
        }
      }
 
      ajax.send(formData)
}

We will use the same P-256 curve algorithm to import the private and public keys we used to exporting it. Then we will create derived key from both (private and public) keys. We will use the derived key, IV and encoded message to encrypt the message. Once the message is encrypted, we will convert the encrypted message and IV to base64 string and send them in the AJAX request. IV will be used to decrypt the message. Then we will create a file named send-message.php to save the data in the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
require_once "db.php";
 
$sender = $_POST["sender"];
$receiver = $_POST["receiver"];
$message = $_POST["message"];
$iv = $_POST["iv"];
 
$sql = "INSERT INTO messages(sender, receiver, message, iv) VALUES (?, ?, ?, ?)";
$result = $conn->prepare($sql);
$result->execute([
  $sender,
  $receiver,
  $message,
  $iv
]);
echo $conn->lastInsertId();

Run the file send.php in the browser. Enter sender and receiver’s email address, type the message and hit “send”. If all goes well, then you will see the inserted message ID in the browser console.

Decrypt message

Now we need to decrypt the encrypted messages. Create a file named read.php. Here we will create a form to enter sender and receiver’s email address to fetch their messages.

1
2
3
4
5
<form onsubmit="readMessages()" id="form-read">
  <input type="email" name="sender" placeholder="Sender email" />
  <input type="email" name="receiver" placeholder="Receiver email" />
  <input type="submit" value="Read" />
</form>

Then we will create a Javascript function that will be called when the above form submits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function readMessages() {
  event.preventDefault()
 
  const form = event.target
  const formData = new FormData(form)
   
  const ajax = new XMLHttpRequest()
  ajax.open("POST", "get-messages.php", true)
  ajax.onreadystatechange = async function () {
    if (this.readyState == 4 && this.status == 200) {
      const response = JSON.parse(this.responseText)
 
      const publicKeyObj = await window.crypto.subtle.importKey(
          "jwk",
          JSON.parse(response.publicKey),
          {
              name: "ECDH",
              namedCurve: "P-256",
          },
          true,
          []
      )
 
      const privateKeyObj = await window.crypto.subtle.importKey(
          "jwk",
          JSON.parse(response.privateKey),
          {
              name: "ECDH",
              namedCurve: "P-256",
          },
          true,
          ["deriveKey", "deriveBits"]
      )
 
      const derivedKey = await window.crypto.subtle.deriveKey(
          { name: "ECDH", public: publicKeyObj },
          privateKeyObj,
          { name: "AES-GCM", length: 256 },
          true,
          ["encrypt", "decrypt"]
      )
 
      for (let a = 0; a < response.messages.length; a++) {
        const iv = new Uint8Array(atob(response.messages[a].iv).split("").map(function(c) {
            return c.charCodeAt(0)
        }))
        const initializationVector = new Uint8Array(iv).buffer
        const string = atob(response.messages[a].message)
        const uintArray = new Uint8Array(
            [...string].map((char) => char.charCodeAt(0))
        )
        const decryptedData = await window.crypto.subtle.decrypt(
            {
                name: "AES-GCM",
                iv: initializationVector,
            },
            derivedKey,
            uintArray
        )
        const message = new TextDecoder().decode(decryptedData)
        console.log(message)
      }
    }
  }
 
  ajax.send(formData)
}

This will call an AJAX request to get the messages. The API will also return the private and public keys required to decrypt the message. Same code can be used to import the keys that we used for sending the message. Create a file named get-messages.php and write the following code in it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
 
require_once "db.php";
 
$sender = $_POST["sender"];
$receiver = $_POST["receiver"];
 
$sql = "SELECT * FROM messages WHERE sender = ? AND receiver = ?";
$result = $conn->prepare($sql);
$result->execute([
  $sender,
  $receiver
]);
$messages = $result->fetchAll(PDO::FETCH_OBJ);
 
$sql = "SELECT privateKey FROM users WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $sender
]);
$userSender = $result->fetchObject();
 
$sql = "SELECT publicKey FROM users WHERE email = ?";
$result = $conn->prepare($sql);
$result->execute([
  $receiver
]);
$userReceiver = $result->fetchObject();
 
echo json_encode([
  "messages" => $messages,
  "privateKey" => $userSender->privateKey,
  "publicKey" => $userReceiver->publicKey
]);
exit();

If you run the read.php file now, you will see the decrypted messages in console tab. However, if you see the “network” tab of browser, you will see that the messages are being returned encrypted from the server. That means that your messages are decrypted online when they arrived on the client side. Thus, they are safe in-transit.

end to end encryption
end to end encryption

That’s how you can do end-to-end encryption in Javascript with PHP and MySQL. No external library has been used in this tutorial, so the code used here will work on all frameworks.

Microservices in NodeJS

Microservices architecture in NodeJS is a group of loosely-coupled services that works independently of each other. Failure in one service does not affect the other services in the system. Consider each service as a separate server or system.

For example, you have a social networking website. So you can create one microservice that handles all functions of users, one microservice for managing posts, one microservice for comments etc.

Today, we are going to create such microservices in Node JS. First, we are going to create 2 microservices. One for handling users and one for posts. Then we will create a gateway that will route the API requests to the relevant service.

  • Directory structure:
    • users
      • server.js
    • posts
      • server.js
    • gateway
      • server.js

Create users microservice

First, we are going to create a microservice for users. Create a folder named users and inside it create a file named server.js. After that, open command prompt or terminal in this users folder and run the following commands one-by-one:

1
2
3
4
> npm init
> npm install -g nodemon
> npm install express
> nodemon server.js

Following will be the code of your server.js file inside users folder.

1
2
3
4
5
6
7
8
9
10
const express = require("express")
const app = express()
 
app.get("/getData", function (request, result) {
    result.send("Get data from users.")
})
 
app.listen(3001, function () {
    console.log("User service is running.")
})

It simply creates a service running at port 3001. This will be your separate server for handling users requests.

Create posts microservice

Now we will create a microservice for handling posts requests. Create a folder named posts and inside it create a file named server.js. After that, open command prompt or terminal in this posts folder and run the following commands one-by-one:

1
2
3
> npm init
> npm install express
> nodemon server.js

The commands are same as we did in users folder. Open the server.js file inside posts folder and write the following code in it.

1
2
3
4
5
6
7
8
9
10
const express = require("express")
const app = express()
 
app.get("/getData", function (request, result) {
    result.send("Get data from posts.")
})
 
app.listen(3002, function () {
    console.log("Post service is running.")
})

It is almost similar to the user’s server.js file. Only the port number is different. It is running on port 3002.

So you have 2 different services that runs independently. If user server fails, the posts server will keep on running independently. Now we need to have a gateway in between them, that will route the users API requests to user’s server and posts API requests to post’s server.

Note that each miroservice should run on a different server or process. Because the whole point of creating microservices is to create loosely-coupled services.

Create a gateway

All the API requests will be sent to the gateway server. The gateway server will then redirect the request to the relevant service.

Create a folder named gateway. Create a file named server.js inside it and open command prompt in it. Then run the following commands in this folder one-by-one:

1
2
3
> npm init
> npm install fast-gateway
> nodemon server.js

We will be using fast-gateway NPM module. Following will be the code of server.js file inside gateway folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const gateway = require("fast-gateway")
 
const server = gateway({
    routes: [
        {
            prefix: "/users",
            target: "http://localhost:3001"
        },
        {
            prefix: "/posts",
            target: "http://localhost:3002"
        }
    ]
})
 
server.get("/serverApi", function (request, result) {
    result.send("Server API is called.")
})
 
server.start(3000).then(function () {
    console.log("Server is started running.")
})

The gateway server will be running on port 3000. Run the following URL in your web browser:

1
http://localhost:3000/users/getData

You will see the message “Get data from users.” So the gateway will automatically route all the requests prefixed with “/users” to the user microservice. Same goes for posts. Run the following URL in web browser:

1
http://localhost:3000/posts/getData

Now you will see the message “Get data from posts.” That’s how you can create microservices in NodeJS.

Add emoji between text – jQuery

In this tutorial, we will teach you, how you can add emoji between text using jQuery. Emoji picker is a library that allows you to select a wide variety of emojis. It is a Javascript library that returns the emoji character. You can append the emoji in your input fields as well.

This library is very useful specially if you are developing a chat app. For example, user can share emojis in messages.

But it has one problem: what happens when user has typed a message, now he wants to add the emoji in between the message ? The library does not provide such functionality by default.

So that we are going to do, is to get the current cursor position on the input field and set the emoji in-between the text.

Requirements:

  1. jQuery
  2. Emoji picker
  3. twemoji

After downloading all the above files, create 2 folders “css” and “js”. Place the CSS files in “css” folder and Javascript files in “js” folder.

After that, you need to include all these files in your code:

1
2
3
4
5
<link rel="stylesheet" href="css/emojis.css" />
 
<script src="js/jquery.js"></script>
<script src="js/DisMojiPicker.js"></script>
<script src="js/twemoji.min.js"></script>

Then, create an input field where you will enter the text and give it a unique ID.

1
<textarea id="textInput"></textarea>

Create a container where the emoji picker will be displayed. Give it a unique ID as well.

1
<div id="emojis"></div>

In your Javascript, initialize the emoji picker.

1
2
3
4
<script>
    $("#emojis").disMojiPicker()
    twemoji.parse(document.body)
</script>

If you refresh the page now, you will start seeing the emoji picker. Now we need to make it to set the emoji in input field.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// callback function that will be called when an emoji is clicked from emoji picker
$("#emojis").picker(function (emoji) {
    // get the current cursor position on textarea field
    const cursorPosition = $("#textInput").prop("selectionStart")
 
    // get the current value of texarea field
    const value = $("#textInput").val()
 
    // check if cursor is at the end of the text
    if (cursorPosition == value.length) {
        // append the emoji at the end
        $("#textInput").val(value + emoji)
    } else {
        // if cursor is in between the text
        // then prepend the emoji before next character
        $("#textInput").val(value.replace(value[cursorPosition], emoji + value[cursorPosition]))
    }
})

We created a single page chat application in MEVN stack where we implemented this emoji picker. You can check that project here.

[wpdm_package id=’2918′]

Custom middleware in Node JS

Middleware in Node JS is called before the request is handled by the router function. They stand between the router and the request. Middlewares are great when it comes to processing and validating request values before they reach the route.

Make sure you have downloaded and installed Node JS in your system first. You can download Node JS from here.

We are going to create a simple middleware that will add a new field “email” with the request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# open terminal at desktop
# following command will create a folder
> mkdir nodejs-middleware
 
# open the folder in command prompt
> cd nodejs-middleware
 
# create a file named "server.js" in that folder
# following command will initialize the project
> npm init
 
# install express module
> npm install express
 
# start the server
> node server.js

Now in our server.js file, we will first start the server.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// server.js
 
// include express module
const express = require("express")
 
// create instance of express module
const app = express()
 
// get the port number if already set, or 3000 otherwise
const port = process.env.PORT || 3000
 
// start the server at specified port
app.listen(port)
 
// test in browser

Make sure to restart the server using “node server.js” command. Now we will create our custom middleware.

1
2
3
4
5
6
7
8
// create a custom middleware
const myMiddleware = function (request, result, next) {
    // add "email" field with the request object
    request.email = "support@adnan-tech.com"
   
    // continue with the request
    next()
}

The following code will add the middleware to all the requests.

1
2
// attach middleware to all requests
app.use(myMiddleware)

The following code will add the middleware to specific requests only.

1
2
3
4
5
// attach middleware to specific request
app.get("/", myMiddleware, function (request, result) {
    // display "email" value on browser
    result.send(request.email)
})

Restart the server and check in your browser: http://localhost:3000

External middleware in Node JS

You can create your middleware in a separate file as well in your Node JS server. Create a file named “external-middleware.js” at the root of your project and write the following code in it:

1
2
3
4
module.exports = function (request, result, next) {
    request.email = "adnan@gmail.com"
    next()
}

Then in your “server.js” file, use the middleware like the following:

1
2
const externalMiddleware = require("./external-middleware")
app.use(externalMiddleware)

To test this middleware, remove or comment out the previous middleware and refresh your browser again. Check out our android application’s tutorial we created on Node JS.