Skip to content

Commit

Permalink
Code for new blog post
Browse files Browse the repository at this point in the history
  • Loading branch information
ralscha committed May 3, 2018
1 parent 351cbd3 commit 342adb9
Show file tree
Hide file tree
Showing 18 changed files with 838 additions and 0 deletions.
1 change: 1 addition & 0 deletions passwordcheck/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Code for the blog post:
17 changes: 17 additions & 0 deletions passwordcheck/client/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
# editorconfig.org

root = true

[*]
indent_style = space
indent_size = 2

# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
3 changes: 3 additions & 0 deletions passwordcheck/client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.cache/
dist/
node_modules/
21 changes: 21 additions & 0 deletions passwordcheck/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "passwords",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "parcel serve src/index.html",
"prebuild": "shx rm -rf dist/*",
"build": "parcel build src/index.html --public-url ."
},
"license": "ISC",
"devDependencies": {
"parcel-bundler": "1.7.1",
"shx": "0.2.2"
},
"dependencies": {
"babel-polyfill": "6.26.0",
"hibp": "7.1.1",
"zxcvbn": "4.4.2"
}
}
44 changes: 44 additions & 0 deletions passwordcheck/client/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Passwords</title>
<link rel="stylesheet" type="text/css" href="./main.css">
</head>
<body>

<section>
<h2>zxcvbn</h2>
<input type="password" name="password" id="password">
<meter max="4" id="password-strength-meter"></meter>
<p id="password-strength-text"></p>
Show Password <input type="checkbox" id="showPasswordFlag">
</section>

<hr>

<section>
<h2>hibp</h2>
<input type="password" name="password" id="password_hibp">
<p id="password_hibp_output"></p>
</section>

<hr>

<section>
<h2>passpol</h2>
<input type="password" name="password" id="password_passpol">
<p id="password_passpol_output"></p>
</section>

<hr>

<section>
<h2>self hosted hibp</h2>
<input type="password" name="password" id="password_shhibp">
<p id="password_shhibp_output"></p>
</section>

<script src="./init.js"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions passwordcheck/client/src/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import 'babel-polyfill';
import { main } from './main';

main();
76 changes: 76 additions & 0 deletions passwordcheck/client/src/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
* {
box-sizing: border-box;
}

body {
padding: 0.5em;
background: #f5f7f9;
font-size: 1.1em;
color: #346;
font-family: Signika, -apple-system, sans-serif;
}

section {
margin: 0em auto 0;
width: 100%;
max-width: 800px;
}

input[name="password"] {
display: block;
margin: .5em auto 0em;
padding: 0.5em 1em 0.5em 0.7em;
width: 100%;
border: none;
background: rgba(0,0,0,0.05);
color: rgba(0,0,0,0.8);
font-size: 2em;
line-height: 0;
transition: all .5s linear;
}

input:hover, input:focus {
outline: 0;
transition: all .5s linear;
box-shadow: inset 0px 0px 10px #ccc;
}

meter {
/* Reset the default appearance */
margin: 0 auto 1em;
width: 100%;
height: .5em;

/* Applicable only to Firefox */
background: none;
background-color: rgba(0,0,0,0.1);
}

meter::-webkit-meter-bar {
background: none;
background-color: rgba(0,0,0,0.1);
}

meter[value="0"]::-webkit-meter-optimum-value,
meter[value="1"]::-webkit-meter-optimum-value { background: red; }
meter[value="2"]::-webkit-meter-optimum-value { background: yellow; }
meter[value="3"]::-webkit-meter-optimum-value { background: orange; }
meter[value="4"]::-webkit-meter-optimum-value { background: green; }

meter[value="1"]::-moz-meter-bar,
meter[value="1"]::-moz-meter-bar { background: red; }
meter[value="2"]::-moz-meter-bar { background: yellow; }
meter[value="3"]::-moz-meter-bar { background: orange; }
meter[value="4"]::-moz-meter-bar { background: green; }

.feedback {
color: #9ab;
font-size: 90%;
padding: 0 .25em;
font-family: Courgette, cursive;
margin-top: 1em;
}

meter::-webkit-meter-optimum-value {
transition: width .4s ease-out;
}
120 changes: 120 additions & 0 deletions passwordcheck/client/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import zxcvbn from 'zxcvbn';
import { pwnedPassword } from 'hibp';

export function main() {

const strength = {
0: "Worst ☹",
1: "Bad ☹",
2: "Weak ☹",
3: "Good ☺",
4: "Strong ☻"
}

const password = document.getElementById('password');
const meter = document.getElementById('password-strength-meter');
const text = document.getElementById('password-strength-text');

password.addEventListener('input', () => {
const val = password.value;
const result = zxcvbn(val);

meter.value = result.score;

if (val !== "") {
text.innerHTML = "Strength: " + "<strong>" + strength[result.score] + "</strong>" + "<span class='feedback'>" + result.feedback.warning + " " + result.feedback.suggestions + "</span";
}
else {
text.innerHTML = "";
}
});

showPasswordFlag.addEventListener('change', () => {
const x = document.getElementById("password");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
});

const password_hibp = document.getElementById('password_hibp');
const output = document.getElementById('password_hibp_output');

let timeoutId = 0;

password_hibp.addEventListener('input', () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(checkHibp, 500);
});

async function checkHibp() {
try {
const numPwns = await pwnedPassword(password_hibp.value);
if (numPwns > 0) {
output.innerHTML = `Password found ${numPwns} of times in the haveibeenpwned.com database`;
} else {
output.innerHTML = `Password not found in the haveibeenpwned.com database`;
}
} catch (err) {
output.innerHTML = err;
}
}


const password_passpol = document.getElementById('password_passpol');
const output_passpol = document.getElementById('password_passpol_output');

password_passpol.addEventListener('input', () => {
output_passpol.innerHTML = '';
clearTimeout(timeoutId);
timeoutId = setTimeout(checkPasspol, 500);
});

async function checkPasspol() {
if (password_passpol.value !== '') {
try {
const response = await fetch('http://localhost:8080/passpolCheck', {
body: password_passpol.value,
method: 'POST'
});
const status = await response.json();
output_passpol.innerHTML = status;

} catch (err) {
output_passpol.innerHTML = err;
}
}
}


const password_shhibp = document.getElementById('password_shhibp');
const output_shhibp = document.getElementById('password_shhibp_output');

password_shhibp.addEventListener('input', () => {
output_shhibp.innerHTML = '';
clearTimeout(timeoutId);
timeoutId = setTimeout(checkSelfHostedHibp, 500);
});

async function checkSelfHostedHibp() {
if (password_shhibp.value !== '') {
try {
const response = await fetch('http://localhost:8080/selfHostedHibpCheck', {
body: password_shhibp.value,
method: 'POST'
});
const status = await response.json();
if (status === 0) {
output_shhibp.innerHTML = `This password wasn't found in any of the Pwned Passwords loaded into Have I Been Pwned`;
} else {
output_shhibp.innerHTML = `This password has been seen ${status} times before<br>
This password has previously appeared in a data breach and should never be used. If you've ever used it anywhere before, change it!`;
}

} catch (err) {
output_shhibp.innerHTML = err;
}
}
}
}
25 changes: 25 additions & 0 deletions passwordcheck/server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/target/
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
Binary file not shown.
1 change: 1 addition & 0 deletions passwordcheck/server/.mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
Loading

0 comments on commit 342adb9

Please sign in to comment.