At work I’m starting to package an Ionic App for Android and it’s been one problem after another (I spent most of yesterday afternoon dealing with a version incompatibility with my NPM libraries and installing Android Studio). Today I ran into a problem getting the application to compile. I’m documenting the solution here because I’m sure I’ll have a problem with it again.
This is the error I received:
A problem occurred configuring root project 'android'.
> You have not accepted the license agreements of the following SDK components:
[Android SDK Platform 26].
Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
Alternatively, to learn how to transfer the license agreements from one workstation to another, go to http://d.android.com/r/studio-ui/export-licenses.html
After some Googling I was able to determine I needed to run:
~/Library/Android/sdk/tools/bin/sdkmanager --licenses
After this you’ll need to press Y until you receive:
What commands can I use to create and manage users and
groups from the command shell of an Amazon Elastic Compute Cloud (Amazon
EC2) Ubuntu Linux instance?
The following commands are used to create and manage users
from the command shell of an EC2 Ubuntu Linux instance. For more
information about these commands, including optional switches and
configuration values, see Ubuntu Manuals - 18.04 LTS. adduser adduser
adds users based on command-line options and configuration variables in
the /etc/adduser.conf file. The adduser command must be preceded by the
sudo qualifier to temporarily grant the necessary privileges. Typically
user names are lower-case letters. You can use a dash (-) or an
underscore (_) in a user name. If you use Samba, user names can end in a
dollar sign ($).
For example, the following command creates the new user account bob.
sudo adduser bob
Add the command-line switch --ingroup GROUP to add the new user to a different group.
The following command creates the new user account bob and adds them to the betausers user group:
sudo adduser bob --ingroup betausers
For a comprehensive list of adduser configuration variables, see adduser.conf. addgroup addgroup
adds groups based on command-line options and configuration variables
in the /etc/adduser.conf. The addgroup command must be preceded by the
sudo qualifier to temporarily grant the necessary privileges. Typically
group names are lower-case letters. You can use a dash (-) or an
underscore (_) in a group name
For example, the following command creates the new group betausers.
sudo addgroup betausers
For a comprehensive list of configuration variables, see adduser.conf. deluser deluser
removes users from the system or from the specified group based on
command-line options and configuration variables in the
/etc/deluser.conf file. The deluser command also can delete a group
itself. The deluser command must be preceded by the sudo qualifier to
temporarily grant the necessary privileges.
The following command deletes the user account bob.
sudo deluser bob
Add the command-line switch --group groupname to delete user from a specific group (but leaves the user in the system).
The following command removes the user bob from the betausers group.
sudo deluser bob --group betausers
The following command removes the group betausers from the system.
sudo deluser --group betausers
For a comprehensive list of configuration variables, see deluser.conf. delgroup delgroup removes groups based on command-line options and configuration variables in the /etc/deluser.conf file. The delgroup command must be preceded by the sudo qualifier to temporarily grant the necessary privileges.
For example, the following command deletes the group betausers.
sudo delgroup betausers
Additional commands for managing users and groups
chage - Change the expiration time for a user's password.
chfn - Change a user name and/or associated user information.
The "DetectionOnly" says Apache not to block any requests which may
be valid in the context of your application instead log the suspicious
requests to error.log.
It is recommended to run the application in "DetectionOnly" mode for a
couple of days or so to avoid the false negative. For instance, in
Drupal 7 some administrative pages (Panel Edit) & Views AJAX
pager stopped working when "SecRuleEngine" to "ON".
Once the error log is reviewed & parameters are tweaked to meet the application needed SecRuleEngine can be changed On.
SecRuleEngineOn
Mod security relies on a set of parameters rule to gauze a request as
genuine or malicious. The following steps would help us place the rule
in place,
cd /etc/httpd/modsecurity.d
sudo wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.0/master.zip
sudo unzip master.zip
sudo mv owasp-modsecurity-crs-3.0-master modsecurity-crs
cd /etc/httpd/modsecurity.d/modsecurity-crs
sudo cp crs-setup.conf.example crs-setup.conf
Add the following line to your httpd.conf. You can alternatively place these in any config file included by Httpd:
# Enable/Disable SSL for this virtual host. SSLEngine on
# A self-signed (snakeoil) certificate can be created by installing # the ssl-cert package. See # /usr/share/doc/apache2/README.Debian.gz for more info. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. SSLCertificateFile /etc/ssl/<b3efe8f8f7a6b2fd>.crt SSLCertificateKeyFile /etc/ssl/<site>.key SSLCertificateChainFile /etc/ssl/<gd_bundle-g2-g1>.crt
So, do you
like socket.io? Once you’ve got the hang of it, it’s not really
complicated getting used to using Node.js. You can see that all sorts of
possibilities are suddenly open to us. Imagine what you can start doing
in real time - chat, games, collaborative work tools, etc.
Amongst
all of these possibilities, I think that chat is by far the simplest
app to create that’s both useful and efficient and will impress your
friends and family. So, let’s go! I
know, most of the socket.io courses already explain how to create a
chat app... but I bet none of them has shown you how to create a "Super Chat"! (in case you're wondering, there's no difference... except for the pretty cool name)
Before we do anything else, look at the next figure. It shows you what our chat looks like.
I
deliberately opened 2 windows here. The left one is connected to the
"mateo21" username and the right one to the "gerry" username.
I ask for the username with a dialog box when the person connects to the website
I show the username of the person who just connected to everyone in the chat (e.g. "gerry joined the chat!")
When we type a message, it’s immediately displayed in the browser under the form.
Basically,
nothing complicated! But even though it’s based on codes from the
previous chapter, you’re going to have to work a bit and think. And
that’s exactly the diabolical plan that I have in mind: to make you
work.
Need help?
Are you lost? Don’t know where to start?
Let’s
go, if you followed the previous chapter on socket.io it shouldn’t be
too difficult. Because I’m such a nice guy, I’ll give you a few clues to
help you along.
A little reminder of what you have to do:
Now let’s ask ourselves the right questions. How many files are we going to need? To me it’s obvious, I would say three:
A package.json file that describes the dependencies of your Node.js project.
An app.js file for the server-side application in Node.js.
An index.html that contains the web page and the chat management client-side code.
Here’s a bit of help for you to create each of these files. If you genuinely feel OK about it, try not to use it. (And worst case scenario you can come back to this section if you get stuck.)
package.json
At
this stage, you should know how to create a package.json with your eyes
closed. I shouldn’t have to explain the syntax to you again, if you’ve
had a memory lapse, I’ll let you go back to the relevant section
"Declaring and publishing your module" in this chapter.
However,
when it comes to external modules, what are we going to need? Here is
what I’d suggest (and what I use in my correction):
socket.io: if you’ve forgotten it, that’s unforgivable.
express:
whilst we’re at it, we might as well use Express.js right from the
start. We didn’t use it in the socket.io chapter but it’s not very
complicated to use alongside socket.io. On their website there’s an explanation of how to use it in combination with Express.js.
ent:
a tiny module that protects the character strings sent by visitors to
change the entities of the HTML. This saves visitors from sending each
other JavaScript in the chat!
Frankly,
Express.js and ent aren’t essential to make the chat work. We can
easily do without them, but I chose them, partly simplify maintenance of
the code (for Express.js) and for security (for ent).
app.js
This
should send a webpage when we call the server. It’s up to you to send
an "index.html" file to your visitors when they connect to your website.
With Express.js, the syntax is a bit different but also shorter.
As
well as the "classic" webpage, your Node.js server will need to
generate socket.io events. In theory, I would say that you only need to
generate two:
new_client
(call it what you want): signals that a new client has logged on to the
chat and should transmit their username to inform the clients with a
message such as "robert has joined the chat!".
message:
signals that a new message has been posted. Your role, as a server, is
simply to redistribute it to other clients who are connected with a
little broadcast. Whilst we’re at it, collect the poster’s username in a
session variable.
In the end, the app.js file isn’t too big or complicated. The more I look at it, the more I find it really short and simple.
index.html
In
truth, it’s may be the file that needs most work and that should give
you a (little) bit of trouble. You’ll need to handle a fair amount of
client-side JavaScript.
Start by structuring a basic HTML5 page with a title, a form made up of a text field and a button, and a<div>or a<section>that will contain the chat messages (by default, it will be empty).
It’s
up to you then to write the client’s JavaScript code. Personally, I put
it at the bottom of the page (for performance reasons, it’s a good
habit to get into). I could also have put an external .js file, but I
didn’t do it here.
This code will need to:
Connect to socket.io.
Ask for the visitor’s username when the page loads (via aprompt()in JS, it’s the most simple one that I found) and send a "new_client" signal.
Manage
the reception of "new_client" signals sent by the server. This means
that a new client has logged on. Display their name in a message, for
example "Robert has joined the Chat!".
Manage
the reception of "message" signals sent by the server. It means that
another client has sent a message in the chat and that it therefore
needs to be shown on the page.
Manage
sending the form when the client wants to send a message to the other
people who are connected. You’ll need to retrieve the message typed in
the JavaScript form, emit a message signal to the server so that it
distributes it to the other clients, and also embed the message into
your own page. Oh yes, don’t forget that the broadcast from the server
sends the message to all the other people who are connected… except to
you. You therefore need to update your own chat zone.
I’ve prepared the work so much that it’s starting to get me down… If you can’t do it with all of this… try harder!
Correction
If everything’s wrong, it’s time for correction!
So,
how did the creation of the chat go for you? You shouldn’t have
encountered too many problems; this practical exercise was a way to
reformulate the chapter before the introduction to socket.io a little
more concisely.
My project is made up of 3 files:
package.json: the description of the project with the list of its dependencies. Any self-respecting Node.js project has one!
app.js: the server-side Node.js app that manages the interactions with the different clients.
index.html: the webpage sent to the client that contains JavaScript code to generate the chat on the client-side.
package.json
{
"name": "super-chat",
"version": "0.1.0",
"dependencies": {
"express": "~3.3.4",
"socket.io": "~1.2.1",
"ent": "~0.1.0"
},
"author": "Mateo21 <mateo21@email.com>",
"description": "A real-time super chat with socket .io"
}
As
I was saying (for those who read the tips earlier on), I obviously use
socket.io, but also Express.js (even though it’s not complulsory) and
ent (to call a function equivalent tohtmlentities()in PHP, to secure exchanges and prevent clients from sending each other malicious JavaScript codes).
app.js
The chat’s server code is relatively short and wasn’t the hardest file to write in practice.
varapp=require('express')(),
server=require('http').createServer(app),
io=require('socket.io').listen(server),
ent=require('ent'),// Blocks HTML characters (security equivalent to htmlentities in PHP)
The
start of the file doesn’t contain anything extraordinary: a few calls
to modules, the management of the index ("/") where we send back
index.html… Seriously, it doesn’t get any easier than that.
Underneath,
there’s all the management of real-time messages with socket.io. In
reality, we only manage two different types of messages:
new_client: sent by a new client who just loaded the page. It contains their username as a setting. I chose to encode it (withent.encode())
for security reasons. So, if the visitor puts JavaScript in their
username, we’re covered! Then, I only need to "save" this username in a
session variable.
message:
sent by the client who wants to send a message to other people who are
connected. Firstly, we encode the message (to be safe from malicious
JavaScript codes) and broadcast it with the username that we saved as a
session variable. To send more data in one setting, I encapsulate them
in a JavaScript object, which gives this code{username: username, message: message}.
That’s all the server has to do!
index.html
OK, the client code is a tad more complicated. But just a tad, honestly.
Here we go, we’ll explain it all afterwards, I promise:
The
slightly complex part is in the JavaScript code at the end of the file.
This is where we find all that we need on the client-side to manage the
chat:
The socket.io connection
The
username request and its transfer to the server via a "new_client"
signal. The added bonus - I allowed myself to display the username in
the<title>of the page so
that it appears in the tabs of my navigator. Given that for my tests I
have multiple tabs open, it helps me remember who’s who!
The
retrieval of the message signal sent by the server. In this case, I
insert the message in the page’s #chat_zone. I chose to create a
function for that because I also need this function when sending the
form.
The retrieval of the "new_client" signal where I display "XXX has joined the chat!".
The
management of sending the form can be the hardest part. You need to
retrieve the message typed by the client, send it to the server, and
insert it in our page (because the server transmits the message to
everyone except for us!). I also made the most of it, emptied the text
zone, and put the focus back on it… and I blocked the ability to send
the form the ‘classic’ way. Thereturn falseis essential if we don’t want the page to reload after the form has been sent. In fact,return falseis equivalent to the jQuerypreventDefault()function.
Finally,
the insertMessage() function is actually very simple. It adds the
message that was sent with its username at the top of the chat form. The
prepend() function is part of jQuery, I didn’t invent it.
I
chose to use jQuery in my code for practical reasons, but you can of
course use JavaScript to do all of this if you want to (or use a
different library).
Basically,
the JavaScript code on the client’s side is probably the biggest part.
The Node.js server part is, as you can see, very simple: we connect,
send signals, retrieve signals… that’s it!
Downloading the project
You already have everything you need but if you really want a .zip file, I suggest you download it on the following link:
Do
you want more practice in using socket.io? Here are some ideas to keep
you busy for a while (by approximate order of difficulty)!
Display a message to the other people when a person disconnects.
Allow clients to change their username in the middle of a chat session.
Try adding buttons to the page to make pre-loaded sounds play at a distance. A little "ding" to wake up sleeping clients?
Try
to save the messages in the memory on the server so that the list of
the latest messages can be displayed when we connect. You can save
information in the memory as we learnt… or try to couple Node.js with a
MySQL, MongoDB, redis, etc. database.
What if your clients could send each other images as well as text?
If despite all this, you’re still bored, take the code for the to do list practical exercise
and make a "to do list that’s shared in real time by several people".
The addition or deletion of tasks will automatically be carried out on
the other clients’ list!