main.append(addBanner("<a href='https://www.linkedin.com/learning/getting-started-as-a-full-stack-web-developer?contextUrn=urn%3Ali%3AlyndaLearningPath%3A59370541498ec352a683231c'>Getting Started as a Full Stack Web Developer</a>","Tom Geller","Developing Your Website Safely"))
main.append(addArticle())
constarticle=document.querySelector("article")
article.append(addParagraph("This chapter covers topics such as developing locally with some kind of AMP stack (MAMP, LAMP, WAMP etc) which I will ignore. In the case of local development, I am already familar with a WAMP stack and since I already have a web server setup, I am not really developing locally in the strictest sense, it just so happens that the remote server is sitting on my desk within arms reach. It might be helpful if I briefly mention how I do develop and this is really what is being covered by the first three videos in this chapter and possibly the fourth."))
article.append(addParagraph("The actual development is performed on a PC with Dreamweaver. For this page, and most of the pages I am writing at the moment, I have a skelton HTML file which calls in a JavaScript file specific to this page so the HTML document is called safely.html and the JavaScript file is called safely.js."))
article.append(addParagraph("The file, safely.js file calls in several other JavaScript files which contain functions for generating HTML. For example, this paragraph is created using a function called addParagraph() which takes a string as an argument and then adds a paragraph to the HTML with that string as the text."))
article.append(addParagraph("Another function is addImageWithCaption() which takes two strings as an argument. The first string is a the image's filename including a relative path and the second string is the caption that goes with it. This generates a figure element with an image that has that the value of its src attrbiute set to the first string and its alt attribute set to the second string. The figure also has a figCaption element whose innerText attribute also uses the second string as a value."))
article.append(addParagraph("It is debatable as to whether this makes development easier but my methodology has changed since I started to learn more JavaScript and it will likely change again in the future."))
article.append(addParagraph("My web server is a Raspberry Pi 4 and I connect to it in two ways. One is via WinSCP which I use to transfer the files from my PC to a directory in my home folder on the Pi. WinSCP is configured to sync the directory on the PC where Dreamweaver saves the files I develop with the folder on the Pi so whenever I save a file locally, it is automatically transferred over to the web server."))
article.append(addParagraph("I also connect to the web server via SSH (I use Kitty to do that) and from there, I can copy the files over to the HTML folder on the web server and I do that with the command"))
article.append(addInset("webcopy"))
article.append(addParagraph("Don't worry if you don't recognise that command, it is actually an alias I use so that I don't have to type the whole command every time I want to copy files over to the live site. The alias is stored in .bashrc in my home directory and this file is shown in figure 14."))
article.append(addImageWithCaption("./images/bash_aliases.png","Figure 14 - my .bash_aliases file."))
article.append(addParagraph("As you can see from figure 14, I also have an alias to cd to the directory containing the live site to make it easier to access it if I need to check or edit a file directly on the server. I don't do that very often but it can be handy if there is something that I am having problems with such as CSS which I can edit directly and instantly see the effect of so this is similar to changing the CSS in the browser's Developer Tools."))
article.append(addParagraph("To sum up, the process of developing the site is really a three step process with the second step being automated."))
article.append(addInset("Step 1, I edit a file in Dreamweaver and save it to the local directory."))
article.append(addInset("Step 2, WinSCP monitors the local directory for any changes and copies the changed file to a directory on thw web server."))
article.append(addInset("Step 3, I copy the files on the server to the HTML folder containing the live site with webcopy."))
article.append(addParagraph("There are several advantages to working this way, but this might not be completely clear when it comes to the way I use JavaScript to generate the HTML. This makes life easier when creating figure elements but is probably more work when it comes to adding paragraphs. The advantage is that it is relatively easy to change the overall structure of the HTML. For example, if I want to add a class to all of the paragraph elements, I only need to do that in the JavaScript file that contains the addParagraph() function so I don't have to go through existing pages to update each one which is something I have had to do in the past. So this gives me more flexibility to change the website and this is important, I think, for a beginner in Web Development because you will change the structure of your pages as you become more knowledgeable and experienced."))
article.append(addParagraph("I do already have a Git account but I actually use BitBucket for version control and I have also completed Christina Truong's course, <a href='https://www.linkedin.com/learning/programming-foundations-version-control-with-git'>Programming Foundations:@ Version Control with Git and you can see my notes from that course <a href'/webdevelopment/versioncontrolwithgit/versioncontrolwithgit.html'>here</a>. I also recently setup my own Git server using a service called Gitea to connect to it. At this stage, I have pushed my first set of files over to the server but I have not yet fully migrated to it so I am still using BitBucket for now. Note that BitBucket is used as a learning aid in Christina's course."))
article.append(addParagraph("Now, let's get back to the course."))
article.append(addHeader("Move Files Between Local and Remote Storage"))
article.append(addParagraph("I am more or less skipping over this section, but there was one point which I think is worth mentioning. In an earlier chapter, we looked at connecting to a remote host via SSH from VisualStudio Code. I never got that to work but since I don't need it, I haven't made much of an effort to resolve the issue there. However, if you do develop via VS Code with a connection to your remote host, this can be an easy way to transfer files between your local machine and the remote host."))
article.append(addHeader("Protect Your Site"))
article.append(addParagraph("Obviously, site security is a very big subject and cannot be covered in a single video lasting less than 5 minutes. The goals in this section are to provide some hints for making your site more secure and some resources to go to for more information and, of course, there are lots of LinkedIn Learning covering various aspects of web security. So you can consider this section to be a starting point in site security and a pointer to some of the things you may want study in future."))
article.append(addParagraph("We will start by looking at those hints."))
article.append(addParagraph("You should never assume that if a user is supposed to enter a specific type of data into an input box, that they will input the right type of data. This applies to almost all areas of programming, not just Web Development. In many cases, entering the wrong type of input will have no real effect other than, perhaps, weird output. For example, if you enter your date of birth instead of your name in the reservation form, you will just get some output where your date of birth appears instead of your name. In somce circumstances, however, deliberately adding the wrong type of input can be a form of attack, an example of this being an SQL inection attack where a user enters an SQL command to manipulate your database."))
article.append(addParagraph("A good example of this is the famous Bobby Tables cartoon from the website xkcd.com created by Randall Munroe and reproduced below in figure 15 with permission."))
article.append(addImageWithCaption("./images/bobby_tables.png","Figure 15 - Bobby Tables from xkcd.com."))
article.append(addParagraph("You can get a fairly good explanation of how the attack in the Booby Tables cartoon works on the <a href='https://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables'>xkcd wiki</a>."))
article.append(addParagraph("Later in the course, we will explore the topic of adding the data a user enters in our reservatin form into a database and at the point, the website can become more vulnerable to this type of attack so we will look at ways to avoid such problems."))
article.append(addSubHeader("HINT 2 - Hide Your Secrets"))
article.append(addParagraph("We have seen that it is possible to view a websites HTML, CSS and even JavaScript in the browser's Developer Tools. This is not true of server side languages such as PHP, but depending on how you write your code, this can still present a danger in several ways. For example, if you upload your site files to an online repository such as Git, even your PHP files may be accessible there and they will be unless you tell Git to ignore any PHP files, or at least any that contain sensitive information such as usernames and passwords."))
article.append(addParagraph("Another potential vulnerability is where you allow users to browse files on your site. What this means is that if a user navigates to a folder where there is no default web page (usually that will be index.html or index.php), the user will instead see a list of files available "))
article.append(addParagraph("At the moment, my website allows browsing and you can see the result of navigating to a folder without a default file in figure 16."))
article.append(addImageWithCaption("./images/browsing_files.png","Figure 16 - an index of files where the web server allows browsing."))
article.append(addParagraph("We can fix this by editing our web server's config file and both the name and location of this can differ depending on both the server you are using and the specific operating system. On a Raspberry Pi, the config file is called apache2.conf and is in the folder"))
article.append(addInset("/etc/apache2/"))
article.append(addParagraph("This is where Apache stores its config files so there are a number of other config files in this folder. If we open up the apache2.conf file, we want to search for FollowSymLinks and we should find this in a block of code that starts <Directory /var/www/> and the line we are interested in is"))
article.append(addParagraph("This is an Apache directive and it is this that allows a user to browse the files as a directory in a web browser. If we comment out that line and restart apache with"))
article.append(addParagraph("we can then go and refresh our webpage and we will no longer see the index of files in that folder. Instead, we will see the ominous message displayed in the image in figure 16."))
article.append(addImageWithCaption("./images/not_browsing_files.png","Figure 16 - an error message where the web server does not allow browsing."))
article.append(addParagraph("Even if you allow browsing of files, users may not be able to download or view certain files depending on other settings but as a general rule, it is safer to simply not allow browsing in this way."))
article.append(addSubHeader("HINT 3 - Use Proven Methods (or Best Practices)"))
article.append(addParagraph("You may be tempted to want to write your own code for everything on a website, particularly if you are learning Web Development. But you should remember that any problem you want to solve with your code has probably already been solved by someone else."))
article.append(addParagraph("The importance of this may not be immediately obvious and it may seem that the difference between the two approaches is simply the amount of work you have to do yourself and you might even be wondering what this has to do with protecting your site!"))
article.append(addParagraph("Consider thiks example. Let's say that you want to add an option to your site allowing users to sign in. You can write your own sign in form or you could find a form on the Internet that someone has already produced. You should be careful where you get code for use in your website and consider the source and whether this is likely to be better or safer than self-written code. However, with a little bit of care, you should be able to find code for this that has already been fully tested and has most of its kinks ironed out. Code that you write yourself won't be as robust and is more likely to contain errors."))
article.append(addParagraph("You may feel as a learner, that it is perfectly fine to have errors in your code and that you can learn from them and that is true but you should also bear in mind a couple of other points. Firstly, while errors can be useful to learn from, you probably want to avoid the type of error that compromises the security of your site!"))
article.append(addParagraph("The second reason is also very important for someone learning web development and that is that by searching and locating code that does what you want and can be considered reliable is a very good habit to get in to and prepares you better to work as a web developer, in some ways, that writing your own code would. As a new employee, you will be expected to resolve problems in a timely manner and writing your own code when you don't have to is not a very good way to do that!"))
article.append(addHeader("HINT 4 - Backup"))
article.append(addParagraph("Saving your files to an online respoitory like BitBucket or GitHub is a good way to back up your files but it is not perfect. If you lose your copy of the website files, you can only recover these from the last point at which you saved your files to the online repository, although in all honesty, this is a shortcoming of any type of backup."))
article.append(addParagraph("You may find, in fact, that the best backup you have is the copy on the web server because this is most likely to be up to date with your local copy. For myself, this is an advantage of automatically copying files to the web server because it means that I have at least one copy on the web server that is always in sync with the local copy. This means that in the event of losing all of my files on the local machine, I will only lose the changes made since I last saved the files in Dreamweaver."))
article.append(addParagraph("The downside is that both the local copy and the server copy are physically in the same location. This means that in the event of something truly catastrophic such as a house fire, all of my files would be lost - potentially!"))
article.append(addParagraph("An added layer of security that I have is that I save my local files to a directory that syncs with OneDrive so I do have an offsite backup that is as up to date as the copy on the web server and that is that it matches the local files the last time I saved them."))
article.append(addParagraph("I do also take backups of all of the files, possibly not as regularly as I should and this process is not automated, which it should be. All things considered, I think that I have a reasonably secure system for ensuring I always have a backup of my files. I think that the important points to take from this are that are that you can never be too safe when it comes to ensuring your data so it is a good idea to have it backed up in several different ways abd in more than one location."))
article.append(addParagraph("If you are intersted in web security in general as you should be if you are interested in full stack development, the following are a good starting point."))
article.append(addInset("<a href='https://www.linkedin.com/learning/programming-foundations-web-security-2'>Programming Foundations: Web Security</a>"))
article.append(addParagraph("This looks like a good course for giving you a background in Web Security and it covers topics such as sanitizing data and common attacks."))
article.append(addInset("<a href='https://www.linkedin.com/learning/ssl-certificates-for-web-developers'>SSL Certificates for Web Developers</a>"))
article.append(addParagraph("This is sloghtly more specialised course but it seems to proivde a good unserstanding of SSL, HTTPS and certificates in general. This is a useful course for web developers and a really useful chapter if you are in the process of setting up your first website is Configure a Web Server to Requires HTTPS."))
article.append(addHeader("Create a Production Workflow"))
article.append(addParagraph("This is a topic that is easy to overlook as you start out in your learning to become a web developer. You might look at courses on topics such as HTML, CSS or JavaScript as a starting point and then move on to PHP or client side libraries such as Angular or React because if you look at job postings for Web Developers, these tend to be the things that recruiters look for."))
article.append(addParagraph("There are good reasons for that, but you will find it a little bit easier to deal with interviews for Web Developer roles if you have some familiary with the soft skills required to produce a software product such as a website."))
article.append(addParagraph("This can be highlighted with a quick humorous aside. In 2021, police in Texas broadcast (via their website) an amber alert about a missibf, possible abducted child named Glen, who happens to be the son of the horror-movie character, Chucky. Chucky himself was declared to be the main suspect in this alleged crime."))
article.append(addParagraph("You can get more info on this on the <a href='https://nerdist.com/article/amber-alert-chucky-childs-play/'>nerdist.com</a> website which also gives an explanation of how this happened. As it turns out, this was a test alert which had been placed into a live environment. Before I explain that any further, take a look at the image in figure 17."))
article.append(addImageWithCaption("./images/sd_stages.png","Figure 17 - different stages of a software development project."))
article.append(addParagraph("As is suggested here, there are three (at least) different approaches to developing a software project. The first is essentially the approach I am using for this website. I develop a page and put it straight onto the web server so it goes live straight away. That's fine for a website like this and it really means that any testing, spell checking etc that I do is being done on the live site that anyone can view."))
article.append(addParagraph("The second approach uses two stages. Development is done in private, possibly locally but certainly on a machine that is not accessible to the public. In the second stage, you can publish your content to the web server. The big advantage here is that you can do as much checking to ensure that your website looks exactly the way you want it to, the links all work and that there are no embarrassing errors (ike a fugitive alert for Chucky)."))
article.append(addParagraph("The third approach adds am intermediary stage where the produce is staged in private between the two stages from the previous approach. Essentially, this means that you are making a version of the produce available in a limited way, perhaps on a web server that isn't publicly accessible. This allows you to essentially publish your content to the 'internet' without making it available to the general public."))
article.append(addParagraph("One of the advantages of this is that you may have a team of developers working on a website so having the intermediary stage allows you to get the code from different developers together, essentially constructing the produce from various sources and allows this to be managed. For example, you may have two developers whose code conflicts - maybe they style the same elements differently - one mighr prefer a font-size of 14 pixels for a paragraph, another may perfer 16 pixels. It is important to have someone whose role (or at least part of their role) is to decide which option to keep when there is a conflict like this."))
article.append(addParagraph("There are other factors which make a multi-staged approach more attractive. For example, you might develop on a Windows machine and deploy the site on a Linux machine and you have to be aware of the differences between the platforms and the facilities they do or do not offer."))
article.append(addParagraph("The main point to take from this is that working in a production environment can be more complex than working on a personal project and it is important to be aware of that."))
article.append(addParagraph("As ever, as you develop your skills in this area, there are plenty of courses available on LinkedIn Learning to support you in that and that includes the following."))
article.append(addParagraph("This goes into the topic of different approaches to developing a system in much more detail. There are lots of other courses on DevOps but this looks like a good introduction and if you want to go into even more detail, there is a Learning Path with a total length of 40 hours that includes 25 courses and includes the Foundations course vur also covers sich tools as Chef/Puppet, Git and Docker as well as other management courses. The path is called <a href='https://www.linkedin.com/learning/paths/become-a-devops-engineer'>Become a DevOps Engineer</a>."))
article.append(addParagraph("THis covers more of the management rather than the development of projects and is probably most useful if you intend to get into project management but it does cover some topics such as the Waterfall and Agile methodologies that may be useful for developers. There are also several related Learning Paths including <a hre='https://www.linkedin.com/learning/paths/become-a-software-project-manager'>Become a Software Project Manager</a> which is 16 hours long and is made up of 12 courses. These are heavily biased towards Agile and particularly Scrum."))
article.append(addParagraph("If you want to dive deeper into Agile, the <a href='https://www.linkedin.com/learning/paths/master-agile-software-development'>Master Agile Software Development</a> path might be a good choice. The fact that it is made up of 33 courses with a total time of 43 hours might seem a little daunting but it also should tell you that the path covers a lot of topics in detail."))
article.append(addInset("<a href='https://www.linkedin.com/learning/software-development-life-cycle-sdlc'>Software Development Life Cycle (SDLC)</a>"))
article.append(addParagraph("This course is similar in some ways to the project management course in that it covers both the Agile and Waterfall methodologies in some detail and some others such as Six Sigma briefly but I would assume these are more from the perspective of a developer. If you were to choose this as a possible starting point for further learning, you are probably more interested in software development."))
article.append(addParagraph("As such, if you wanted to follow a Learning Path, good options might include the <a href='https://www.linkedin.com/learning/paths/become-a-software-developer'>Become a Software Developer Path</a> which is 30 hours long and includes 11 courses. This is a kind of generic programming path and includes web programming languages, adding Python, Java, C# and SQL as well as a few more generic programming courses. If you are interested in doing this after completing a web development path, you will most likely find that you have already completed some of these courses. For example, I have completed 4 of the courses on this path with a total time of nearly 14 hours so that would shorten this path for me."))
article.append(addParagraph("If you don't want to become a developer, another option would be to become a tester, which might point you towards the <a href='https://www.linkedin.com/learning/paths/become-a-software-tester'>Become a Software Tester</a> which is made up of 13 courses and has a total time of 17 and a half hours. It covers some basic testing courses as well as some popular topics such as Agile or API Testing and some common tools such as Selenium or JUnit."))