Browse Source

Initial Commit

pull/1/head
Levi Olson 6 years ago
parent
commit
03961c29d7
19 changed files with 3507 additions and 0 deletions
  1. +2
    -0
      .gitignore
  2. +21
    -0
      README.md
  3. +77
    -0
      app.js
  4. +217
    -0
      core.css
  5. +2654
    -0
      package-lock.json
  6. +18
    -0
      package.json
  7. +133
    -0
      posts/i-can-crack-your-password.html
  8. +9
    -0
      posts/i-can-crack-your-password.json
  9. +4
    -0
      posts/something-decent.html
  10. +9
    -0
      posts/something-decent.json
  11. +45
    -0
      views/pages/404.ejs
  12. +62
    -0
      views/pages/about.html
  13. +53
    -0
      views/pages/index.ejs
  14. +46
    -0
      views/pages/post.ejs
  15. +56
    -0
      views/pages/posts.ejs
  16. +69
    -0
      views/pages/uncopyright.html
  17. +9
    -0
      views/partials/footer.ejs
  18. +7
    -0
      views/partials/head.ejs
  19. +16
    -0
      views/partials/header.ejs

+ 2
- 0
.gitignore View File

@ -0,0 +1,2 @@
.vscode
node_modules

+ 21
- 0
README.md View File

@ -0,0 +1,21 @@
# How does this work
_This file is intended to help you remember the thing you made way back then..._
## Instructions
1. Create your html file and put it in `/posts`
2. Then create the meta file for it of the same name but using the ext `.json`. This file should look like:
{
"title": "Something Decent - Levi Olson",
"permalink": "/posts/something-decent",
"created_at": "2018-04-27T17:05:19-06:00",
"created_at_short": "2018-04-27",
"post_title": "the start of something... decent",
"active": "posts",
"content_file": "something-decent.html",
"categories" : ["misc", "programming", "js", "etc..."]
}
3. That's it.

+ 77
- 0
app.js View File

@ -0,0 +1,77 @@
'use strict'
const express = require('express')
const fs = require('fs')
const path = require('path')
const app = express()
app.set('view engine', 'ejs')
app.get('/', (req, res) => {
res.render('pages/index', {
title: "Levi Olson",
active: "home",
content: ""
})
})
app.get('/posts', (req, res) => {
const postDir = __dirname + '/posts'
let files = fs.readdirSync(postDir, 'utf8')
let data = {
title: "Posts - Levi Olson",
active: "posts",
posts: []
}
for (let i = 0; i < files.length; i++) {
if (path.extname(files[i]) === '.json') {
data.posts.push(getData(files[i]))
}
}
res.render('pages/posts', data)
})
function getData(file) {
let postData
try {
postData = JSON.parse(fs.readFileSync('./posts/' + file, 'utf8'))
postData.content = fs.readFileSync('./posts/' + postData.content_file, 'utf8')
} catch (e) {
return
}
return postData
}
app.get('/about', (req, res) => {
res.sendFile(__dirname + '/views/pages/about.html')
})
app.get('/uncopyright', (req, res) => {
return res.sendFile(__dirname + '/views/pages/uncopyright.html')
})
app.get('/404', (req, res) => {
return res.status(404).render('pages/404', {
title: "Page Not Found - Levi Olson",
active: ""
})
})
app.get('/core.css', (req, res) => {
res.sendFile(__dirname + '/core.css')
})
app.get('/posts/:post', (req, res) => {
let post = req.params.post
let postData
try {
postData = JSON.parse(fs.readFileSync('./posts/' + post + '.json', 'utf8'))
postData.content = fs.readFileSync('./posts/' + postData.content_file, 'utf8')
} catch (e) {
return res.redirect('/404')
}
return res.render('pages/post', postData)
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))

+ 217
- 0
core.css View File

@ -0,0 +1,217 @@
body {
font-family: Hack, Menlo, Monaco, Ubuntu Mono, monospace;
font-size: 14px;
color: #ddd;
background: #222;
padding: 20px;
margin: 0;
display: flex;
justify-content: center;
line-height: 1.5;
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
code,
kbd,
tt,
var {
font-size: 14px;
}
article h1,
h2,
h3,
h4,
h5,
h6 {
padding: 20px 0 20px 0
}
blockquote {
border-left: 5px solid #ddd;
margin: 0;
padding: 0 20px 0 20px;
margin: 0 0 40px 0;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 700px;
align-items: center;
}
header {
padding-top: 20px;
padding-bottom: 40px;
}
footer.footer-container {
align-self: left;
padding-top: 120px;
}
div.site {
align-items: center;
width: 100%;
}
a {
color: #fff;
}
a:hover {
color: #999;
}
a:visited {
color: #eee;
}
code {
color: #ddd;
background: #333;
}
pre {
background: #333;
}
.main-menu a,
.social-menu a {
color: #ddd;
}
.main-menu-container {
margin-top: 0em;
}
nav {
width: 100%;
}
nav ul {
padding: 0 0 100px 0;
margin: 0;
}
nav ul li {
font-size: 14px;
display: inline-block;
text-transform: lowercase;
}
nav ul li.logo a {
text-decoration: none;
}
nav ul li a:hover {
border-bottom: none;
color: #999;
}
.title {
margin-bottom: 0;
text-transform: none;
color: #ddd;
padding-bottom: 0;
}
main {
align-self: left;
}
div.meta {
padding-right: 10px;
}
.list-item-header h3,
header {
padding: 0;
margin: 0;
}
article li {
list-style-type: square;
}
.list {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
margin: 0;
padding: 0;
list-style: none;
}
.list-item article {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: baseline;
-ms-flex-align: baseline;
align-items: baseline;
}
pre {
padding: 20px 10px;
}
code {
color: lightcoral;
}
pre>code {
color: #ddd;
}
.mute {
color: #999;
}
/*
Hack Font
*/
@font-face {
font-family: 'Hack';
src: url('fonts/hack-regular.woff2?sha=e700a30') format('woff2'), url('fonts/hack-regular.woff?sha=e700a30') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Hack';
src: url('fonts/hack-bold.woff2?sha=e700a30') format('woff2'), url('fonts/hack-bold.woff?sha=e700a30') format('woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Hack';
src: url('fonts/hack-italic.woff2?sha=e700a30') format('woff2'), url('fonts/hack-italic.woff?sha=e700a30') format('woff');
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'Hack';
src: url('fonts/hack-bolditalic.woff2?sha=e700a30') format('woff2'), url('fonts/hack-bolditalic.woff?sha=e700a30') format('woff');
font-weight: 700;
font-style: italic;
}

+ 2654
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 18
- 0
package.json View File

@ -0,0 +1,18 @@
{
"name": "levi",
"version": "1.0.0",
"description": "",
"main": "app.js",
"dependencies": {
"ejs": "^2.5.9",
"express": "^4.16.3",
"nodemon": "^1.17.3"
},
"devDependencies": {},
"scripts": {
"start": "./node_modules/.bin/nodemon app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

+ 133
- 0
posts/i-can-crack-your-password.html View File

@ -0,0 +1,133 @@
<p>You may think your password is secure. Maybe you have chosen an obscure word, mixed in numbers, and added a
<code>!</code> to the end. Think you’re pretty safe, huh?</p>
<p>The truth is, you aren’t. I can crack a 5 character password in less then 139 seconds!</p>
<p>We have been trained over time, by
<em>unproven</em> security techniques, to make our passwords contain numbers and letters; sometimes even an
<code>@</code> or
<code>#</code> or
<code>!</code> is added to the mix.
<strong>But</strong> the truth is, we are only making it harder on ourselves with passwords that are difficult to remember, but
easy to guess in a brute-force attack (automated hacking software).</p>
<p>Although a 128-character
<em>totally random</em> password would be phenomenal, 8 characters is about all that can be enforced without frustrating
users. However, an 8-character password comprised of uppercase, lowercase, and numbers can be cracked overnight in a
real world brute-force attack.</p>
<h2 id="the-scoop-on-alpha-numeric-passwords">The Scoop on Alpha-Numeric Passwords</h2>
<p>Even though we are trained to think that a password of
<code>Blu3D0g5</code> is the most secure type of password, it can still be cracked by a brute-force attack.
</p>
<p>Bare with me while I explain…
<em>with some maths!</em>
</p>
<p>For every character in an alpha-numeric password there are
<code>62</code> possibilities. First, you have the
<code>26</code> character alphabet in lowercase, then
<code>26</code> more in uppercase, and
<code>10</code> digits.</p>
<div>
<pre style="text-align: center;"><code>26 + 26 + 10 = 62</code></pre>
</div>
<p>This is to say that if you choose 8 characters,
<em>completely at random</em>, your password would be very secure. However, we typically take a familiar word, or couple
of words, and add some uppercase letters, or replace
<code>e</code> with
<code>3</code>, etc… which is
<strong>not</strong> secure.</p>
<p>When we calculate the Information Entropy (known as the lack of order or predictability) we can see that a completely random
character set is great, but when it is derived from an English word, or contains a date, it is simply terrible. The equation
looks like this:</p>
<div>
<pre style="text-align: center;"><code>[Password_Length] * log2([Number_of_Possibilities]) = "Information Entropy"</code></pre>
</div>
<div>
<pre><code>8 * log2(62) = "~48 bits"
# which would take almost 9,000 years at 1,000 guesses per second</code></pre>
</div>
<p>
<em>But, when your password isn’t
<strong>completely</strong> random, it’s not that simple.</em>
</p>
<p>Because the password we chose was actually two words,
<code>blue</code> and
<code>dogs,</code> with some uppercase and numbers mixed in, the total Entropy is
<strong>MUCH</strong> less. Something closer to
<code>~28 bits</code>.</p>
<p>
<strong>So let’s calculate what this actually means.</strong> A brute-force attacker can easily guess 1,000 times per second.
The total number of options to guess can be calculated by taking the base 2 to the total number of bits.</p>
<div>
<pre><code>2^28 = 268,435,456
# This is the total number of possibilities the password could be.</code></pre>
</div>
<p>In theory though, an attacker only needs to guess about half the total number of options before stumbling upon the correct
one. So:</p>
<div>
<pre><code>268,435,456 / 2 = 134,217,728
# Total number of guesses it takes to guess your password
134,217,728 / 1,000 = ~134,218
# At 1,000 guesses per second, it takes about 134,218 seconds
134,218 / 60 = ~2,237
# Or 2,237 minutes
2,237 / 60 = ~37
# Or 37 hours to guess your password</code></pre>
</div>
<hr>
<h2 id="in-contrast">In Contrast</h2>
<p>Let’s say we use 4
<strong>random</strong> words, without any numbers, and all lowercase. For example:
<code>yellow</code>
<code>tiger</code>
<code>note</code>
<code>basket</code>. There are an incalculable amount of words for you to choose from, but most likely, you will choose from
about 7,000 of the most commonly used words. If you use unique words like
<code>laggardly</code> or
<code>pomological</code>, the total time to crack your password will increase
<strong>exponentially</strong>!</p>
<p>Using this new data, the Information Entropy is now calculated as:</p>
<div>
<pre style="text-align: center;"><code>[Number_of_words] * log2(7,000)</code></pre>
</div>
<p>So, this new password now has
<code>~51 bits</code> of Entropy, and using the same time calculations above, we estimate our password would take about
<code>35,702 years</code> to crack at the rate of 1,000 guesses per second.</p>
<p>That is in stark contrast to the short 37 hours it takes to crack the
<code>Blu3D0g5</code> password.</p>
<hr>
<h2 id="the-take-away">The Take Away</h2>
<p>By simply increasing the length of our passwords and using words randomly mixed together, we can have the most secure passwords
that attackers will struggle to figure out, but that we can actually remember. I personally will never forget
<code>yellow</code>
<code>tiger</code>
<code>note</code>
<code>basket</code> as long as I live. However, now I can’t use it.</p>

+ 9
- 0
posts/i-can-crack-your-password.json View File

@ -0,0 +1,9 @@
{
"title": "I can crack your password - Levi Olson",
"permalink": "/posts/i-can-crack-your-password",
"created_at": "2018-04-27T07:05:32-06:00",
"created_at_short": "2018-04-27",
"post_title": "i can crack your password",
"active": "posts",
"content_file": "i-can-crack-your-password.html"
}

+ 4
- 0
posts/something-decent.html View File

@ -0,0 +1,4 @@
<blockquote>
<p>the start of something... decent</p>
</blockquote>
<p>I don't expect to have a lot to say, but when I do, I'd like a place to put it.</p>

+ 9
- 0
posts/something-decent.json View File

@ -0,0 +1,9 @@
{
"title": "Something Decent - Levi Olson",
"permalink": "/posts/something-decent",
"created_at": "2018-04-27T17:05:19-06:00",
"created_at_short": "2018-04-27",
"post_title": "the start of something... decent",
"active": "posts",
"content_file": "something-decent.html"
}

+ 45
- 0
views/pages/404.ejs View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="home type-page">
<div class="container">
<% include ../partials/header %>
<main class="main" id="main">
<article class="entry">
<header class="header-container">
<div class="header entry-header">
<div class="header-info">
<h1 class="title">
404
</h1>
</div>
<div class="meta">
<span class="posted-on">
<time class="date" datetime="2018-04-27T17:05:19-06:00"></time>
</span>
</div>
</div>
</header>
<div class="entry-content">
<h2>What on earth are your trying to pull hot shot.</h2>
<a href="/">Turn around</a>
</div>
<footer class="entry-footer-container">
<div class="entry-footer">
</div>
</footer>
</article>
</main>
<% include ../partials/footer %>
</div>
</body>
</html>

+ 62
- 0
views/pages/about.html View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>Levi Olson</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link rel="stylesheet" href="core.css"> -->
<style>
body {
background-color: #222 !important;
color: #fff !important;
font-family: monospace !important;
font-size: 20px !important;
line-height: 1.4 !important;
padding-top: 120px !important;
padding-bottom: 60px !important;
overflow-x: none !important;
}
main {
padding-right: 10px !important;
padding-left: 10px !important;
margin-right: auto !important;
margin-left: auto !important;
max-width: 600px !important;
min-width: 280px !important;
}
a {
text-decoration: none !important;
outline: none !important;
font-weight: bold !important;
color: #777 !important;
}
a:hover,
a:active,
a:focus {
color: #888 !important;
}
</style>
</head>
<body>
<main>
<p>
Owner of
<a href="https://securepass.io/" target="_blank">this company</a>,
<br />former Senior Software Engineer at
<a href="https://carsforsale.com" target="_blank">this company</a>,
<br /> look what
<a href="https://github.com/leothelocust">I can do</a>,
<br /> contact me
<a href="mailto:me@leviolson.com">here</a>
<br /> or read stuff I write
<a href="/posts">here</a>.
</p>
</main>
</body>
</html>

+ 53
- 0
views/pages/index.ejs View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="home type-page">
<div class="container">
<% include ../partials/header %>
<main class="main" id="main">
<article class="entry">
<header class="header-container">
<div class="header entry-header">
<div class="header-info">
<h1 class="title">
<a href="/"></a>
</h1>
</div>
<div class="meta">
<span class="posted-on">
<time class="date" datetime="2018-04-27T17:05:19-06:00"></time>
</span>
</div>
</div>
</header>
<div class="entry-content">
<p>So, we've been trying to get our 5 yr old son to finish drinking his milk.</p>
<p>One of the ways we have encourage him is to explain that milk contains proteins that
are good for the body and help build strong muscles. Skim is good, 1% is good, 2% is even better.
</p>
<p>He thought for a while, and said...<br /><br /></p>
<blockquote>
<p>Dad, have you been drinking 100% milk?
<br />Cause your muscles are sooo big!
</p>
</blockquote>
<p>And that my friends is why being a dad is the best.</p>
</div>
<footer class="entry-footer-container">
<div class="entry-footer">
</div>
</footer>
</article>
</main>
<% include ../partials/footer %>
</div>
</body>
</html>

+ 46
- 0
views/pages/post.ejs View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="home type-page">
<div class="container">
<% include ../partials/header %>
<main class="main" id="main">
<article class="entry">
<header class="header-container">
<div class="header entry-header">
<div class="header-info">
<h1 class="title">
<a href="<%= permalink %>"><%= post_title %></a>
</h1>
</div>
<div class="meta">
<span class="posted-on">
<time class="date" datetime="<%= created_at %>"><%= created_at_short %></time>
</span>
</div>
</div>
</header>
<div class="entry-content" style="padding-top: 50px;">
<%- content %>
</div>
<footer class="entry-footer-container" style="padding-top:100px;">
<div class="entry-footer">
<p>- until next time.</p>
</div>
</footer>
</article>
</main>
<% include ../partials/footer %>
</div>
</body>
</html>

+ 56
- 0
views/pages/posts.ejs View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<% include ../partials/head %>
</head>
<body class="home type-page">
<div class="container">
<% include ../partials/header %>
<main id='main' class='main'>
<header class='header-container'>
<div class='header list-header'>
<div class='header-info'>
<h1 class='title'>Posts</h1>
</div>
</div>
</header>
<div class='list-container'>
<ul class='list'>
<% posts.forEach(function(post) { %>
<li class='list-item'>
<article>
<div class='meta'>
<span>
<time datetime='<%= post.created_at %>'><%= post.created_at_short %></time>
</span>
</div>
<header class='list-item-header'>
<h3 class='list-item-title'>
<a href='<%= post.permalink %>'><%= post.title %></a>
</h3>
</header>
</article>
</li>
<% }) %>
</ul>
</div>
</main>
<footer id='footer' class='footer-container'>
<div class='footer'>
<div class='copyright'>
<p>
<a href='/uncopyright'>uncopyright</a>
</p>
</div>
</div>
</footer>
</div>
</div>
</body>
</html>

+ 69
- 0
views/pages/uncopyright.html View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>uncopyright</title>
<link rel='stylesheet' href='core.css'>
</head>
<body class='page type-page layout-simple'>
<div class="container">
<nav>
<ul>
<li>
<a href="/">home</a>
</li>
<li>
<a href="/posts">posts</a>
</li>
<li>
<a href="/about">about</a>
</li>
<li>
<a href="https://github.com/leothelocust">projects</a>
</li>
</ul>
</nav>
<main id='main' class='main'>
<article lang='en' class='entry'>
<div class='entry-content'>
<p>Based on the
<a href="http://mnmlist.com/uncopyright/" target="_blank">license from mnmlist</a>.</p>
<p>This site is exists without copyrights. Its creator has released all claims on copyright and has
<strong>put all the content into the public domain.</strong>
</p>
<p>No permission is needed to copy, distribute, or modify the content of this site. Credit is appreciated
but not required.</p>
<p>
<strong>Terms and Conditions for Copying, Distribution and Modification</strong>
</p>
<ul>
<li>Do whatever you like.</li>
</ul>
</div>
</article>
</main>
<footer id='footer' class='footer-container'>
<div class='footer'>
<div class='copyright'>
<p>
<a href='/uncopyright'>uncopyright</a>
</p>
</div>
</div>
</footer>
</div>
</div>
</body>
</html>

+ 9
- 0
views/partials/footer.ejs View File

@ -0,0 +1,9 @@
<footer id="footer" class="footer-container">
<div class="footer">
<div class="copyright">
<p>
<a href="/uncopyright">uncopyright</a>
</p>
</div>
</div>
</footer>

+ 7
- 0
views/partials/head.ejs View File

@ -0,0 +1,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>
<%= title %>
</title>
<link rel="stylesheet" href="/core.css">

+ 16
- 0
views/partials/header.ejs View File

@ -0,0 +1,16 @@
<nav>
<ul>
<li class="<% if (active == 'home') { %> logo <% } %>">
<a href="/">home</a>
</li>
<li class="<% if (active == 'posts') { %> logo <% } %>">
<a href="/posts">posts</a>
</li>
<li>
<a href="/about">about</a>
</li>
<li>
<a href="https://github.com/leothelocust">projects</a>
</li>
</ul>
</nav>

Loading…
Cancel
Save