make Prettier™
This commit is contained in:
parent
137990002a
commit
513fb992c9
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": true
|
||||||
|
}
|
15
README.md
15
README.md
|
@ -1,10 +1,8 @@
|
||||||
Greenlock™ in your Browser
|
# Greenlock™ in your Browser
|
||||||
=========================
|
|
||||||
|
|
||||||
Taking greenlock™ (Let's Encrypt v2 / ACME client) where it's never been before: Your browser!
|
Taking greenlock™ (Let's Encrypt v2 / ACME client) where it's never been before: Your browser!
|
||||||
|
|
||||||
Official Site
|
# Official Site
|
||||||
=============
|
|
||||||
|
|
||||||
This app is available at <https://greenlock.domains>.
|
This app is available at <https://greenlock.domains>.
|
||||||
|
|
||||||
|
@ -14,14 +12,12 @@ If it doesn't, please open an issue to let us know why.
|
||||||
We'd much rather improve the app than have a hundred different versions running in the wild.
|
We'd much rather improve the app than have a hundred different versions running in the wild.
|
||||||
However, in keeping to our values we've released the source for others to inspect, improve, and modify.
|
However, in keeping to our values we've released the source for others to inspect, improve, and modify.
|
||||||
|
|
||||||
Trademark Notice
|
# Trademark Notice
|
||||||
================
|
|
||||||
|
|
||||||
Greenlock™ is our trademark. If you do host your own copy of this app,
|
Greenlock™ is our trademark. If you do host your own copy of this app,
|
||||||
please do provide attribution, but please also use your branding.
|
please do provide attribution, but please also use your branding.
|
||||||
|
|
||||||
Install
|
# Install
|
||||||
=======
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone ssh://gitea@git.coolaj86.com:22042/coolaj86/greenlock.html.git
|
git clone ssh://gitea@git.coolaj86.com:22042/coolaj86/greenlock.html.git
|
||||||
|
@ -30,8 +26,7 @@ pushd greenlock.html/
|
||||||
popd
|
popd
|
||||||
```
|
```
|
||||||
|
|
||||||
Usage
|
# Usage
|
||||||
=====
|
|
||||||
|
|
||||||
Simply host from your webserver.
|
Simply host from your webserver.
|
||||||
|
|
||||||
|
|
364
app/index.html
364
app/index.html
|
@ -1,46 +1,79 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Greenlock™</title>
|
<title>Greenlock™</title>
|
||||||
<meta property="og:image" content="https://greenlock.domains/img/greenlock-mark-400x400.png" />
|
<meta
|
||||||
|
property="og:image"
|
||||||
|
content="https://greenlock.domains/img/greenlock-mark-400x400.png"
|
||||||
|
/>
|
||||||
<style>
|
<style>
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: "Source Sans Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
|
src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
url(./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||||
|
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: "Source Sans Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2');
|
src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
url(./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||||
|
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Code Pro'), local('SourceCodePro-Regular'), url(./fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2) format('woff2');
|
src: local("Source Code Pro"), local("SourceCodePro-Regular"),
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
url(./fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2) format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||||
|
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link href="styles/main.css" rel="stylesheet">
|
<link href="styles/main.css" rel="stylesheet" />
|
||||||
<link rel="preload" href="./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2" as="font" crossorigin="anonymous">
|
<link
|
||||||
<link rel="preload" href="./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2" as="font" crossorigin="anonymous">
|
rel="preload"
|
||||||
|
href="./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2"
|
||||||
<link rel="preload" href="./fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2" as="font" crossorigin="anonymous">
|
as="font"
|
||||||
<link rel="preload" href="./js/bluecrypt-acme.js" as="script">
|
crossorigin="anonymous"
|
||||||
<link rel="preload" href="./js/greenlock.js" as="script">
|
/>
|
||||||
|
<link
|
||||||
|
rel="preload"
|
||||||
|
href="./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2"
|
||||||
|
as="font"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="preload"
|
||||||
|
href="./fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2"
|
||||||
|
as="font"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<link rel="preload" href="./js/bluecrypt-acme.js" as="script" />
|
||||||
|
<link rel="preload" href="./js/greenlock.js" as="script" />
|
||||||
</head>
|
</head>
|
||||||
<body hidden>
|
<body hidden>
|
||||||
<!-- let's define our SVG that we will reuse -->
|
<!-- let's define our SVG that we will reuse -->
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" viewBox="0 0 24 24">
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="0"
|
||||||
|
height="0"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<g id="svg-check">
|
<g id="svg-check">
|
||||||
<path fill="none" d="M0 0h24v24H0z" />
|
<path fill="none" d="M0 0h24v24H0z" />
|
||||||
|
@ -48,10 +81,14 @@
|
||||||
</g>
|
</g>
|
||||||
<g id="svg-checked">
|
<g id="svg-checked">
|
||||||
<path d="M0 0h24v24H0z" fill="none" />
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
<path
|
||||||
|
d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g id="svg-unchecked">
|
<g id="svg-unchecked">
|
||||||
<path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/>
|
<path
|
||||||
|
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
|
||||||
|
/>
|
||||||
<path d="M0 0h24v24H0z" fill="none" />
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
</g>
|
</g>
|
||||||
<g id="svg-download">
|
<g id="svg-download">
|
||||||
|
@ -65,7 +102,11 @@
|
||||||
<div id="js-progress-bar" class="progress-bar">
|
<div id="js-progress-bar" class="progress-bar">
|
||||||
<div class="progress-bar-step">
|
<div class="progress-bar-step">
|
||||||
<div class="circle">
|
<div class="circle">
|
||||||
<svg display="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
display="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-check"></use>
|
<use xlink:href="#svg-check"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,7 +114,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-bar-step">
|
<div class="progress-bar-step">
|
||||||
<div class="circle">
|
<div class="circle">
|
||||||
<svg display="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
display="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-check"></use>
|
<use xlink:href="#svg-check"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,16 +126,22 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-bar-step">
|
<div class="progress-bar-step">
|
||||||
<div class="circle">
|
<div class="circle">
|
||||||
<svg display="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
display="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-check"></use>
|
<use xlink:href="#svg-check"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress-step-label"><div>Install certificates</div></div>
|
<div class="progress-step-label">
|
||||||
|
<div>Install certificates</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- hide until the steps are all updated
|
<!-- hide until the steps are all updated
|
||||||
<div class="progress-bar-step">
|
<div class="progress-bar-step">
|
||||||
<div class="circle">
|
<div class="circle">
|
||||||
<svg display="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg display="none" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
|
||||||
<use xlink:href="#svg-check"></use>
|
<use xlink:href="#svg-check"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,52 +149,112 @@
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
</div>
|
</div>
|
||||||
<div class="greenlock-logo-badge"><img src="./img/greenlock-mark-400x400.png"></div>
|
<div class="greenlock-logo-badge">
|
||||||
|
<img src="./img/greenlock-mark-400x400.png" />
|
||||||
|
</div>
|
||||||
<div class="greenlock-name">Greenlock</div>
|
<div class="greenlock-name">Greenlock</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column-row">
|
<div class="column-row">
|
||||||
<form class="js-acme-form js-acme-form-domains">
|
<form class="js-acme-form js-acme-form-domains">
|
||||||
<h1><label>What's your domain?</label></h1>
|
<h1><label>What's your domain?</label></h1>
|
||||||
<h4>Certificates are valid for 90 days. Renewal is free :)</h4>
|
<h4>Certificates are valid for 90 days. Renewal is free :)</h4>
|
||||||
<input class="js-acme-domains" type="text" placeholder="example.com,*.example.com" required>
|
<input
|
||||||
<br>
|
class="js-acme-domains"
|
||||||
|
type="text"
|
||||||
|
placeholder="example.com,*.example.com"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
<button type="submit">Next</button>
|
<button type="submit">Next</button>
|
||||||
|
|
||||||
<br>
|
<br />
|
||||||
<br>
|
<br />
|
||||||
<br>
|
<br />
|
||||||
<label><input class="js-acme-api-type" name="acme-api-type" type="radio" value="v02" checked required>
|
<label
|
||||||
Production</label>
|
><input
|
||||||
<label><input class="js-acme-api-type" name="acme-api-type" type="radio" value="staging-v02" required>
|
class="js-acme-api-type"
|
||||||
Testing</label>
|
name="acme-api-type"
|
||||||
<br>
|
type="radio"
|
||||||
<input class="js-acme-directory-url" type="url" placeholder="ACME directory url">
|
value="v02"
|
||||||
|
checked
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
Production</label
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
><input
|
||||||
|
class="js-acme-api-type"
|
||||||
|
name="acme-api-type"
|
||||||
|
type="radio"
|
||||||
|
value="staging-v02"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
Testing</label
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
<input
|
||||||
|
class="js-acme-directory-url"
|
||||||
|
type="url"
|
||||||
|
placeholder="ACME directory url"
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Step 2 Create Account -->
|
<!-- Step 2 Create Account -->
|
||||||
<form class="js-acme-form js-acme-form-account">
|
<form class="js-acme-form js-acme-form-account">
|
||||||
<h1><label>What's your email?</label></h1>
|
<h1><label>What's your email?</label></h1>
|
||||||
<input class="js-acme-account-email acme-account-email" type="email" placeholder="john@doe.family" required>
|
<input
|
||||||
|
class="js-acme-account-email acme-account-email"
|
||||||
|
type="email"
|
||||||
|
placeholder="john@doe.family"
|
||||||
|
required
|
||||||
|
/>
|
||||||
<div class="checkbox-array">
|
<div class="checkbox-array">
|
||||||
<label>
|
<label>
|
||||||
<input class="js-acme-account-tos" type="checkbox" required>
|
<input class="js-acme-account-tos" type="checkbox" required />
|
||||||
<svg class="icon-checked-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="icon-checked-box"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-checked"></use>
|
<use xlink:href="#svg-checked"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<svg class="icon-unchecked-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="icon-unchecked-box"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-unchecked"></use>
|
<use xlink:href="#svg-unchecked"></use>
|
||||||
</svg>
|
</svg>
|
||||||
Agree to  <a class="js-acme-tos-url" target="acme-tos">Let's Encrypt™ Terms of Service</a>?
|
Agree to <a class="js-acme-tos-url" target="acme-tos"
|
||||||
|
>Let's Encrypt™ Terms of Service</a
|
||||||
|
>?
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<input class="js-greenlock-account-tos" type="checkbox" required>
|
<input
|
||||||
<svg class="icon-checked-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
class="js-greenlock-account-tos"
|
||||||
|
type="checkbox"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<svg
|
||||||
|
class="icon-checked-box"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-checked"></use>
|
<use xlink:href="#svg-checked"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<svg class="icon-unchecked-box" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="icon-unchecked-box"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-unchecked"></use>
|
<use xlink:href="#svg-unchecked"></use>
|
||||||
</svg>
|
</svg>
|
||||||
Agree to  <a class="js-gl-tos" target="_blank" href="/legal/#terms">Greenlock™ Terms of Service</a>?
|
Agree to  <a
|
||||||
|
class="js-gl-tos"
|
||||||
|
target="_blank"
|
||||||
|
href="/legal/#terms"
|
||||||
|
>Greenlock™ Terms of Service</a
|
||||||
|
>?
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
|
@ -151,28 +262,41 @@
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
-->
|
-->
|
||||||
<button class="button-next js-account-next" type="submit">Next</button>
|
<button class="button-next js-account-next" type="submit">
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
<div class="email-usage">
|
<div class="email-usage">
|
||||||
Why do we need your email?
|
Why do we need your email? We link your SSL certificates to the
|
||||||
We link your SSL certificates to the email you use so that you'll
|
email you use so that you'll be notified before the certificate
|
||||||
be notified before the certificate expires and so you can manage
|
expires and so you can manage your certificates in the future.
|
||||||
your certificates in the future.
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Step 3 Set Challanges -->
|
<!-- Step 3 Set Challanges -->
|
||||||
<form class="js-acme-form js-acme-form-challenges">
|
<form class="js-acme-form js-acme-form-challenges">
|
||||||
|
|
||||||
<h1>Let's verify your domain</h1>
|
<h1>Let's verify your domain</h1>
|
||||||
<div class="js-acme-challenges">
|
<div class="js-acme-challenges">
|
||||||
<div class="tabbed-selector">
|
<div class="tabbed-selector">
|
||||||
<label>
|
<label>
|
||||||
<input class="js-acme-challenge-type" name="acme-challenge-type" type="radio" value="http-01" checked required>
|
<input
|
||||||
|
class="js-acme-challenge-type"
|
||||||
|
name="acme-challenge-type"
|
||||||
|
type="radio"
|
||||||
|
value="http-01"
|
||||||
|
checked
|
||||||
|
required
|
||||||
|
/>
|
||||||
File Upload
|
File Upload
|
||||||
<div></div>
|
<div></div>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<input class="js-acme-challenge-type" name="acme-challenge-type" type="radio" value="dns-01" required>
|
<input
|
||||||
|
class="js-acme-challenge-type"
|
||||||
|
name="acme-challenge-type"
|
||||||
|
type="radio"
|
||||||
|
value="dns-01"
|
||||||
|
required
|
||||||
|
/>
|
||||||
DNS Record
|
DNS Record
|
||||||
<div></div>
|
<div></div>
|
||||||
</label>
|
</label>
|
||||||
|
@ -187,26 +311,35 @@
|
||||||
<div class="file-ver-info-header">FILENAME</div>
|
<div class="file-ver-info-header">FILENAME</div>
|
||||||
<pre class="js-acme-ver-file-location">...loading</pre>
|
<pre class="js-acme-ver-file-location">...loading</pre>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr />
|
||||||
<div>
|
<div>
|
||||||
<div class="file-ver-info-header">CONTENTS</div>
|
<div class="file-ver-info-header">CONTENTS</div>
|
||||||
<pre class="js-acme-ver-content">...loading</pre>
|
<pre class="js-acme-ver-content">...loading</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="download-file">
|
<div class="download-file">
|
||||||
<svg class="mdicon icon-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="mdicon icon-download"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-download"></use>
|
<use xlink:href="#svg-download"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<a class="js-download-verify-link" href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4=" download="hello.txt" target="_blank">
|
<a
|
||||||
|
class="js-download-verify-link"
|
||||||
|
href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4="
|
||||||
|
download="hello.txt"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
Download
|
Download
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr />
|
||||||
<div>
|
<div>
|
||||||
<div class="file-ver-info-header">LOCATION</div>
|
<div class="file-ver-info-header">LOCATION</div>
|
||||||
<pre class="js-acme-ver-uri">..loading</pre>
|
<pre class="js-acme-ver-uri">..loading</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="js-acme-verification-dns-01">
|
<div class="js-acme-verification-dns-01">
|
||||||
|
@ -216,12 +349,16 @@
|
||||||
<div class="js-acme-ver-txt-host">loading...</div>
|
<div class="js-acme-ver-txt-host">loading...</div>
|
||||||
<div class="acme-ver-dns-label">TXT Value</div>
|
<div class="acme-ver-dns-label">TXT Value</div>
|
||||||
<div class="js-acme-ver-txt-value">loading...</div>
|
<div class="js-acme-ver-txt-value">loading...</div>
|
||||||
<br>
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<p><strong>Warning</strong>:
|
<p>
|
||||||
You should wait at least 30 seconds after setting DNS records before continuing.</p>
|
<strong>Warning</strong>: You should wait at least 30 seconds
|
||||||
<p><strong>Google DNS Users</strong>:
|
after setting DNS records before continuing.
|
||||||
You may need to wait up to 5 minutes.</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Google DNS Users</strong>: You may need to wait up to
|
||||||
|
5 minutes.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -233,12 +370,16 @@
|
||||||
<div class="js-acme-ver-txt-host">loading...</div>
|
<div class="js-acme-ver-txt-host">loading...</div>
|
||||||
<div class="acme-ver-dns-label">TXT Value</div>
|
<div class="acme-ver-dns-label">TXT Value</div>
|
||||||
<div class="js-acme-ver-txt-value">loading...</div>
|
<div class="js-acme-ver-txt-value">loading...</div>
|
||||||
<br>
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<p><strong>Warning</strong>:
|
<p>
|
||||||
You should wait at least 30 seconds after setting DNS records before continuing.</p>
|
<strong>Warning</strong>: You should wait at least 30 seconds
|
||||||
<p><strong>Google DNS</strong>:
|
after setting DNS records before continuing.
|
||||||
You may need to wait up to 5 minutes.</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Google DNS</strong>: You may need to wait up to 5
|
||||||
|
minutes.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -252,8 +393,8 @@
|
||||||
<div class="js-challenge-responses" hidden>
|
<div class="js-challenge-responses" hidden>
|
||||||
Checking
|
Checking
|
||||||
<span class="js-challenge-response-altname"> </span>
|
<span class="js-challenge-response-altname"> </span>
|
||||||
using <span class="js-challenge-response-type"> </span>
|
using <span class="js-challenge-response-type"> </span> :
|
||||||
: <span class="js-challenge-response-status"> </span>
|
<span class="js-challenge-response-status"> </span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -286,28 +427,44 @@
|
||||||
<h2><label>privkey.pem</label></h2>
|
<h2><label>privkey.pem</label></h2>
|
||||||
<div class="acme-result-privkey file-preview">
|
<div class="acme-result-privkey file-preview">
|
||||||
<div class="paper-fold"></div>
|
<div class="paper-fold"></div>
|
||||||
<pre id="js-privkey">
|
<pre id="js-privkey"></pre>
|
||||||
</pre>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="download-file">
|
<div class="download-file">
|
||||||
<svg class="mdicon icon-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="mdicon icon-download"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-download"></use>
|
<use xlink:href="#svg-download"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<a id="js-download-privkey-link" href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4=" download="privkey.pem" target="_blank">
|
<a
|
||||||
|
id="js-download-privkey-link"
|
||||||
|
href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4="
|
||||||
|
download="privkey.pem"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
Download
|
Download
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h2><label>fullchain.pem</label></h2>
|
<h2><label>fullchain.pem</label></h2>
|
||||||
<div class="acme-result-fullchain file-preview">
|
<div class="acme-result-fullchain file-preview">
|
||||||
<div class="paper-fold"></div>
|
<div class="paper-fold"></div>
|
||||||
<pre id="js-fullchain">
|
<pre id="js-fullchain"></pre>
|
||||||
</pre>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="download-file">
|
<div class="download-file">
|
||||||
<svg class="mdicon icon-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
<svg
|
||||||
|
class="mdicon icon-download"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewbox="0 0 24 24"
|
||||||
|
>
|
||||||
<use xlink:href="#svg-download"></use>
|
<use xlink:href="#svg-download"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<a id="js-download-fullchain-link" href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4=" download="fullchain.pem" target="_blank">
|
<a
|
||||||
|
id="js-download-fullchain-link"
|
||||||
|
href="data:text/octet-stream;base64,SGVsbG8gV29ybGQuLi4="
|
||||||
|
download="fullchain.pem"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
Download
|
Download
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -340,37 +497,58 @@
|
||||||
<a href="#">Advanced (copy and paste)</a>
|
<a href="#">Advanced (copy and paste)</a>
|
||||||
<br>
|
<br>
|
||||||
<button type="submit">Start Over</button>
|
<button type="submit">Start Over</button>
|
||||||
-->
|
--></div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div><small><center>
|
|
||||||
<div>
|
<div>
|
||||||
A <a href="https://rootprojects.org/" target="_blank">Root</a> Project
|
<small
|
||||||
| <a href="https://git.coolaj86.com/coolaj86/greenlock.html" target="_blank">View Source</a> (git)
|
><center>
|
||||||
| <a href="https://rootprojects.org/legal/#terms" target="_blank">Terms of Service</a>
|
<div>
|
||||||
| <a href="https://rootprojects.org/legal/#privacy" target="_blank">Privacy Policy</a>
|
A
|
||||||
|
<a href="https://rootprojects.org/" target="_blank">Root</a>
|
||||||
|
Project |
|
||||||
|
<a
|
||||||
|
href="https://git.coolaj86.com/coolaj86/greenlock.html"
|
||||||
|
target="_blank"
|
||||||
|
>View Source</a
|
||||||
|
>
|
||||||
|
(git) |
|
||||||
|
<a href="https://rootprojects.org/legal/#terms" target="_blank"
|
||||||
|
>Terms of Service</a
|
||||||
|
>
|
||||||
|
|
|
||||||
|
<a
|
||||||
|
href="https://rootprojects.org/legal/#privacy"
|
||||||
|
target="_blank"
|
||||||
|
>Privacy Policy</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<!-- or
|
<!-- or
|
||||||
<pre><code>git clone https://git.coolaj86.com/coolaj86/greenlock.html.git</code></pre>
|
<pre><code>git clone https://git.coolaj86.com/coolaj86/greenlock.html.git</code></pre>
|
||||||
Or view the live site code (same as live-site branch):
|
Or view the live site code (same as live-site branch):
|
||||||
<pre><code>wget https://greenlock.domains --mirror --convert-links --adjust-extension --page-requisites --no-parent</code></pre>
|
<pre><code>wget https://greenlock.domains --mirror --convert-links --adjust-extension --page-requisites --no-parent</code></pre>
|
||||||
-->
|
-->
|
||||||
</center></small></div>
|
</center></small
|
||||||
<br>
|
>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
<script src="./js/bluecrypt-acme.js"></script>
|
<script src="./js/bluecrypt-acme.js"></script>
|
||||||
<script src="./js/greenlock.js"></script>
|
<script src="./js/greenlock.js"></script>
|
||||||
|
|
||||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-118745161-2"></script>
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-118745161-2"
|
||||||
|
></script>
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag(){dataLayer.push(arguments);}
|
function gtag() {
|
||||||
gtag('js', new Date());
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
gtag('config', 'UA-118745161-2');
|
gtag("config", "UA-118745161-2");
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,45 +1,54 @@
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
/*global URLSearchParams,Headers*/
|
/*global URLSearchParams,Headers*/
|
||||||
var PromiseA = window.Promise;
|
var PromiseA = window.Promise;
|
||||||
var VERSION = '2';
|
var VERSION = "2";
|
||||||
// ACME recommends ECDSA P-256, but RSA 2048 is still required by some old servers (like what replicated.io uses )
|
// ACME recommends ECDSA P-256, but RSA 2048 is still required by some old servers (like what replicated.io uses )
|
||||||
// ECDSA P-384, P-521, and RSA 3072, 4096 are NOT recommend standards (and not properly supported)
|
// ECDSA P-384, P-521, and RSA 3072, 4096 are NOT recommend standards (and not properly supported)
|
||||||
var BROWSER_SUPPORTS_RSA = false;
|
var BROWSER_SUPPORTS_RSA = false;
|
||||||
var ECDSA_OPTS = { kty: 'EC', namedCurve: 'P-256' };
|
var ECDSA_OPTS = { kty: "EC", namedCurve: "P-256" };
|
||||||
var RSA_OPTS = { kty: 'RSA', modulusLength: 2048 };
|
var RSA_OPTS = { kty: "RSA", modulusLength: 2048 };
|
||||||
var Promise = window.Promise;
|
var Promise = window.Promise;
|
||||||
var Keypairs = window.Keypairs;
|
var Keypairs = window.Keypairs;
|
||||||
var ACME = window.ACME;
|
var ACME = window.ACME;
|
||||||
var CSR = window.CSR;
|
var CSR = window.CSR;
|
||||||
var $qs = function (s) { return window.document.querySelector(s); };
|
var $qs = function(s) {
|
||||||
var $qsa = function (s) { return window.document.querySelectorAll(s); };
|
return window.document.querySelector(s);
|
||||||
|
};
|
||||||
|
var $qsa = function(s) {
|
||||||
|
return window.document.querySelectorAll(s);
|
||||||
|
};
|
||||||
var acme;
|
var acme;
|
||||||
var info = {};
|
var info = {};
|
||||||
var steps = {};
|
var steps = {};
|
||||||
var i = 1;
|
var i = 1;
|
||||||
var apiUrl = 'https://acme-{{env}}.api.letsencrypt.org/directory';
|
var apiUrl = "https://acme-{{env}}.api.letsencrypt.org/directory";
|
||||||
|
|
||||||
// fix previous browsers
|
// fix previous browsers
|
||||||
var isCurrent = (localStorage.getItem('version') === VERSION);
|
var isCurrent = localStorage.getItem("version") === VERSION;
|
||||||
if (!isCurrent) {
|
if (!isCurrent) {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
localStorage.setItem('version', VERSION);
|
localStorage.setItem("version", VERSION);
|
||||||
}
|
}
|
||||||
localStorage.setItem('version', VERSION);
|
localStorage.setItem("version", VERSION);
|
||||||
|
|
||||||
function updateApiType() {
|
function updateApiType() {
|
||||||
/*jshint validthis: true */
|
/*jshint validthis: true */
|
||||||
var input = this || Array.prototype.filter.call(
|
var input =
|
||||||
$qsa('.js-acme-api-type'), function ($el) { return $el.checked; }
|
this ||
|
||||||
)[0];
|
Array.prototype.filter.call($qsa(".js-acme-api-type"), function($el) {
|
||||||
|
return $el.checked;
|
||||||
|
})[0];
|
||||||
//#console.log('ACME api type radio:', input.value);
|
//#console.log('ACME api type radio:', input.value);
|
||||||
$qs('.js-acme-directory-url').value = apiUrl.replace(/{{env}}/g, input.value);
|
$qs(".js-acme-directory-url").value = apiUrl.replace(
|
||||||
|
/{{env}}/g,
|
||||||
|
input.value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideForms() {
|
function hideForms() {
|
||||||
$qsa('.js-acme-form').forEach(function (el) {
|
$qsa(".js-acme-form").forEach(function(el) {
|
||||||
el.hidden = true;
|
el.hidden = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -66,7 +75,10 @@
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
window.alert(str);
|
window.alert(str);
|
||||||
if (window.confirm("Start over?")) {
|
if (window.confirm("Start over?")) {
|
||||||
document.location.href = document.location.href.replace(/\/app.*/, '/');
|
document.location.href = document.location.href.replace(
|
||||||
|
/\/app.*/,
|
||||||
|
"/"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
});
|
||||||
|
@ -76,48 +88,66 @@
|
||||||
var j = i;
|
var j = i;
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
||||||
return PromiseA.resolve().then(function () {
|
return PromiseA.resolve()
|
||||||
|
.then(function() {
|
||||||
return steps[j].submit(ev);
|
return steps[j].submit(ev);
|
||||||
}).catch(function (err) {
|
})
|
||||||
|
.catch(function(err) {
|
||||||
var ourfault = true;
|
var ourfault = true;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
if (/failed to fetch/i.test(err.message)) {
|
if (/failed to fetch/i.test(err.message)) {
|
||||||
return newAlert("Network connection failure.");
|
return newAlert("Network connection failure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('E_ACME_CHALLENGE' === err.code) {
|
if ("E_ACME_CHALLENGE" === err.code) {
|
||||||
if ('dns-01' === err.type) {
|
if ("dns-01" === err.type) {
|
||||||
ourfault = false;
|
ourfault = false;
|
||||||
return newAlert("It looks like the DNS record you set for "
|
return newAlert(
|
||||||
+ err.altname + " was incorrect or did not propagate. "
|
"It looks like the DNS record you set for " +
|
||||||
+ "The error message was '" + err.message + "'");
|
err.altname +
|
||||||
} else if ('http-01' === err.type) {
|
" was incorrect or did not propagate. " +
|
||||||
|
"The error message was '" +
|
||||||
|
err.message +
|
||||||
|
"'"
|
||||||
|
);
|
||||||
|
} else if ("http-01" === err.type) {
|
||||||
ourfault = false;
|
ourfault = false;
|
||||||
return newAlert("It looks like the file you uploaded for "
|
return newAlert(
|
||||||
+ err.altname + " was incorrect or could not be downloaded. "
|
"It looks like the file you uploaded for " +
|
||||||
+ "The error message was '" + err.message + "'");
|
err.altname +
|
||||||
|
" was incorrect or could not be downloaded. " +
|
||||||
|
"The error message was '" +
|
||||||
|
err.message +
|
||||||
|
"'"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ourfault) {
|
if (ourfault) {
|
||||||
err.auth = undefined;
|
err.auth = undefined;
|
||||||
window.alert("Something went wrong. It's probably our fault, not yours."
|
window.alert(
|
||||||
+ " Please email aj@rootprojects.org to let him know. The error message is: \n"
|
"Something went wrong. It's probably our fault, not yours." +
|
||||||
+ JSON.stringify(err, null, 2));
|
" Please email aj@rootprojects.org to let him know. The error message is: \n" +
|
||||||
|
JSON.stringify(err, null, 2)
|
||||||
|
);
|
||||||
return new Promise(function() {});
|
return new Promise(function() {});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function testKeypairSupport() {
|
function testKeypairSupport() {
|
||||||
return Keypairs.generate(RSA_OPTS).then(function () {
|
return Keypairs.generate(RSA_OPTS)
|
||||||
|
.then(function() {
|
||||||
console.info("[crypto] RSA is supported");
|
console.info("[crypto] RSA is supported");
|
||||||
BROWSER_SUPPORTS_RSA = true;
|
BROWSER_SUPPORTS_RSA = true;
|
||||||
}).catch(function () {
|
})
|
||||||
|
.catch(function() {
|
||||||
console.warn("[crypto] RSA is NOT supported");
|
console.warn("[crypto] RSA is NOT supported");
|
||||||
return Keypairs.generate(ECDSA_OPTS).then(function () {
|
return Keypairs.generate(ECDSA_OPTS)
|
||||||
console.info('[crypto] ECDSA is supported');
|
.then(function() {
|
||||||
}).catch(function (e) {
|
console.info("[crypto] ECDSA is supported");
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
console.warn("[crypto] EC is NOT supported");
|
console.warn("[crypto] EC is NOT supported");
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
@ -125,8 +155,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getServerKeypair() {
|
function getServerKeypair() {
|
||||||
var sortedAltnames = info.identifiers.map(function (ident) { return ident.value; }).sort().join(',');
|
var sortedAltnames = info.identifiers
|
||||||
var serverJwk = JSON.parse(localStorage.getItem('server:' + sortedAltnames) || 'null');
|
.map(function(ident) {
|
||||||
|
return ident.value;
|
||||||
|
})
|
||||||
|
.sort()
|
||||||
|
.join(",");
|
||||||
|
var serverJwk = JSON.parse(
|
||||||
|
localStorage.getItem("server:" + sortedAltnames) || "null"
|
||||||
|
);
|
||||||
if (serverJwk) {
|
if (serverJwk) {
|
||||||
return PromiseA.resolve(serverJwk);
|
return PromiseA.resolve(serverJwk);
|
||||||
}
|
}
|
||||||
|
@ -139,62 +176,85 @@
|
||||||
keypairOpts = ECDSA_OPTS;
|
keypairOpts = ECDSA_OPTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Keypairs.generate(RSA_OPTS).catch(function (err) {
|
return Keypairs.generate(RSA_OPTS)
|
||||||
console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
|
.catch(function(err) {
|
||||||
|
console.error(
|
||||||
|
"[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):"
|
||||||
|
);
|
||||||
throw err;
|
throw err;
|
||||||
}).then(function (pair) {
|
})
|
||||||
localStorage.setItem('server:'+sortedAltnames, JSON.stringify(pair.private));
|
.then(function(pair) {
|
||||||
|
localStorage.setItem(
|
||||||
|
"server:" + sortedAltnames,
|
||||||
|
JSON.stringify(pair.private)
|
||||||
|
);
|
||||||
return pair.private;
|
return pair.private;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccountKeypair(email) {
|
function getAccountKeypair(email) {
|
||||||
var json = localStorage.getItem('account:'+email);
|
var json = localStorage.getItem("account:" + email);
|
||||||
if (json) {
|
if (json) {
|
||||||
return Promise.resolve(JSON.parse(json));
|
return Promise.resolve(JSON.parse(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Keypairs.generate(ECDSA_OPTS).catch(function (err) {
|
return Keypairs.generate(ECDSA_OPTS)
|
||||||
console.warn("[Error] Keypairs.generate(" + JSON.stringify(ECDSA_OPTS) + "):\n", err);
|
.catch(function(err) {
|
||||||
|
console.warn(
|
||||||
|
"[Error] Keypairs.generate(" + JSON.stringify(ECDSA_OPTS) + "):\n",
|
||||||
|
err
|
||||||
|
);
|
||||||
return Keypairs.generate(RSA_OPTS).catch(function(err) {
|
return Keypairs.generate(RSA_OPTS).catch(function(err) {
|
||||||
console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
|
console.error(
|
||||||
|
"[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):"
|
||||||
|
);
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
}).then(function (pair) {
|
})
|
||||||
localStorage.setItem('account:'+email, JSON.stringify(pair.private));
|
.then(function(pair) {
|
||||||
|
localStorage.setItem("account:" + email, JSON.stringify(pair.private));
|
||||||
return pair.private;
|
return pair.private;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateChallengeType() {
|
function updateChallengeType() {
|
||||||
/*jshint validthis: true*/
|
/*jshint validthis: true*/
|
||||||
var input = this || Array.prototype.filter.call(
|
var input =
|
||||||
$qsa('.js-acme-challenge-type'), function ($el) { return $el.checked; }
|
this ||
|
||||||
)[0];
|
Array.prototype.filter.call($qsa(".js-acme-challenge-type"), function(
|
||||||
$qs('.js-acme-verification-wildcard').hidden = true;
|
$el
|
||||||
$qs('.js-acme-verification-http-01').hidden = true;
|
) {
|
||||||
$qs('.js-acme-verification-dns-01').hidden = true;
|
return $el.checked;
|
||||||
|
})[0];
|
||||||
|
$qs(".js-acme-verification-wildcard").hidden = true;
|
||||||
|
$qs(".js-acme-verification-http-01").hidden = true;
|
||||||
|
$qs(".js-acme-verification-dns-01").hidden = true;
|
||||||
if (info.challenges.wildcard) {
|
if (info.challenges.wildcard) {
|
||||||
$qs('.js-acme-verification-wildcard').hidden = false;
|
$qs(".js-acme-verification-wildcard").hidden = false;
|
||||||
}
|
}
|
||||||
if (info.challenges[input.value]) {
|
if (info.challenges[input.value]) {
|
||||||
$qs('.js-acme-verification-' + input.value).hidden = false;
|
$qs(".js-acme-verification-" + input.value).hidden = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveContact(email, domains) {
|
function saveContact(email, domains) {
|
||||||
// to be used for good, not evil
|
// to be used for good, not evil
|
||||||
return window.fetch('https://api.rootprojects.org/api/rootprojects.org/public/community', {
|
return window
|
||||||
method: 'POST'
|
.fetch(
|
||||||
, cors: true
|
"https://api.rootprojects.org/api/rootprojects.org/public/community",
|
||||||
, headers: new Headers({ 'Content-Type': 'application/json' })
|
{
|
||||||
, body: JSON.stringify({
|
method: "POST",
|
||||||
address: email
|
cors: true,
|
||||||
, project: 'greenlock-domains@rootprojects.org'
|
headers: new Headers({ "Content-Type": "application/json" }),
|
||||||
, timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone
|
body: JSON.stringify({
|
||||||
, domain: domains.join(',')
|
address: email,
|
||||||
|
project: "greenlock-domains@rootprojects.org",
|
||||||
|
timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
|
domain: domains.join(",")
|
||||||
})
|
})
|
||||||
}).catch(function (err) {
|
}
|
||||||
|
)
|
||||||
|
.catch(function(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -203,27 +263,39 @@
|
||||||
console.info("\n1. Show domains form");
|
console.info("\n1. Show domains form");
|
||||||
updateProgress(0);
|
updateProgress(0);
|
||||||
hideForms();
|
hideForms();
|
||||||
$qs('.js-acme-form-domains').hidden = false;
|
$qs(".js-acme-form-domains").hidden = false;
|
||||||
};
|
};
|
||||||
steps[1].submit = function() {
|
steps[1].submit = function() {
|
||||||
console.info("[submit] 1. Process domains, create ACME client", info.domains);
|
console.info(
|
||||||
info.domains = $qs('.js-acme-domains').value
|
"[submit] 1. Process domains, create ACME client",
|
||||||
.replace(/https?:\/\//g, ' ').replace(/[,+]/g, ' ').trim().split(/\s+/g);
|
info.domains
|
||||||
console.info("[domains]", info.domains.join(' '));
|
);
|
||||||
|
info.domains = $qs(".js-acme-domains")
|
||||||
|
.value.replace(/https?:\/\//g, " ")
|
||||||
|
.replace(/[,+]/g, " ")
|
||||||
|
.trim()
|
||||||
|
.split(/\s+/g);
|
||||||
|
console.info("[domains]", info.domains.join(" "));
|
||||||
|
|
||||||
info.identifiers = info.domains.map(function(hostname) {
|
info.identifiers = info.domains.map(function(hostname) {
|
||||||
return { type: 'dns', value: hostname.toLowerCase().trim() };
|
return { type: "dns", value: hostname.toLowerCase().trim() };
|
||||||
});
|
});
|
||||||
info.identifiers.sort(function(a, b) {
|
info.identifiers.sort(function(a, b) {
|
||||||
if (a === b) { return 0; }
|
if (a === b) {
|
||||||
if (a < b) { return 1; }
|
return 0;
|
||||||
if (a > b) { return -1; }
|
}
|
||||||
|
if (a < b) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (a > b) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var acmeDirectoryUrl = $qs('.js-acme-directory-url').value;
|
var acmeDirectoryUrl = $qs(".js-acme-directory-url").value;
|
||||||
acme = ACME.create({ Keypairs: Keypairs, CSR: CSR });
|
acme = ACME.create({ Keypairs: Keypairs, CSR: CSR });
|
||||||
return acme.init(acmeDirectoryUrl).then(function(directory) {
|
return acme.init(acmeDirectoryUrl).then(function(directory) {
|
||||||
$qs('.js-acme-tos-url').href = directory.meta.termsOfService;
|
$qs(".js-acme-tos-url").href = directory.meta.termsOfService;
|
||||||
return steps[i]();
|
return steps[i]();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -233,68 +305,77 @@
|
||||||
|
|
||||||
updateProgress(0);
|
updateProgress(0);
|
||||||
hideForms();
|
hideForms();
|
||||||
$qs('.js-acme-form-account').hidden = false;
|
$qs(".js-acme-form-account").hidden = false;
|
||||||
};
|
};
|
||||||
steps[2].submit = function() {
|
steps[2].submit = function() {
|
||||||
console.info("[submit] 2. Create ACME account (get Key ID)");
|
console.info("[submit] 2. Create ACME account (get Key ID)");
|
||||||
|
|
||||||
var email = $qs('.js-acme-account-email').value.toLowerCase().trim();
|
var email = $qs(".js-acme-account-email")
|
||||||
|
.value.toLowerCase()
|
||||||
|
.trim();
|
||||||
info.email = email;
|
info.email = email;
|
||||||
info.contact = [ 'mailto:' + email ];
|
info.contact = ["mailto:" + email];
|
||||||
info.agree = $qs('.js-acme-account-tos').checked;
|
info.agree = $qs(".js-acme-account-tos").checked;
|
||||||
//info.greenlockAgree = $qs('.js-gl-tos').checked;
|
//info.greenlockAgree = $qs('.js-gl-tos').checked;
|
||||||
|
|
||||||
// TODO ping with version and account creation
|
// TODO ping with version and account creation
|
||||||
setTimeout(saveContact, 100, email, info.domains);
|
setTimeout(saveContact, 100, email, info.domains);
|
||||||
|
|
||||||
$qs('.js-account-next').disabled = true;
|
$qs(".js-account-next").disabled = true;
|
||||||
|
|
||||||
return info.cryptoCheck.then(function () {
|
return info.cryptoCheck
|
||||||
|
.then(function() {
|
||||||
return getAccountKeypair(email).then(function(jwk) {
|
return getAccountKeypair(email).then(function(jwk) {
|
||||||
// TODO save account id rather than always retrieving it?
|
// TODO save account id rather than always retrieving it?
|
||||||
console.info("[accounts] upsert for", email);
|
console.info("[accounts] upsert for", email);
|
||||||
return acme.accounts.create({
|
return acme.accounts
|
||||||
email: email
|
.create({
|
||||||
, agreeToTerms: info.agree && true
|
email: email,
|
||||||
, accountKeypair: { privateKeyJwk: jwk }
|
agreeToTerms: info.agree && true,
|
||||||
}).then(function (account) {
|
accountKeypair: { privateKeyJwk: jwk }
|
||||||
|
})
|
||||||
|
.then(function(account) {
|
||||||
console.info("[accounts] result:", account);
|
console.info("[accounts] result:", account);
|
||||||
info.account = account;
|
info.account = account;
|
||||||
info.privateJwk = jwk;
|
info.privateJwk = jwk;
|
||||||
info.email = email;
|
info.email = email;
|
||||||
}).catch(function (err) {
|
})
|
||||||
|
.catch(function(err) {
|
||||||
console.error("[accounts] failed to upsert account:");
|
console.error("[accounts] failed to upsert account:");
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return newAlert(err.message || JSON.stringify(err, null, 2));
|
return newAlert(err.message || JSON.stringify(err, null, 2));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(function () {
|
})
|
||||||
|
.then(function() {
|
||||||
var jwk = info.privateJwk;
|
var jwk = info.privateJwk;
|
||||||
var account = info.account;
|
var account = info.account;
|
||||||
|
|
||||||
console.info("[orders] requesting");
|
console.info("[orders] requesting");
|
||||||
return acme.orders.request({
|
return acme.orders
|
||||||
account: account
|
.request({
|
||||||
, accountKeypair: { privateKeyJwk: jwk }
|
account: account,
|
||||||
, domains: info.domains
|
accountKeypair: { privateKeyJwk: jwk },
|
||||||
}).then(function (order) {
|
domains: info.domains
|
||||||
|
})
|
||||||
|
.then(function(order) {
|
||||||
info.order = order;
|
info.order = order;
|
||||||
console.info("[orders] created ", order);
|
console.info("[orders] created ", order);
|
||||||
|
|
||||||
var claims = order.claims;
|
var claims = order.claims;
|
||||||
|
|
||||||
var obj = { 'dns-01': [], 'http-01': [], 'wildcard': [] };
|
var obj = { "dns-01": [], "http-01": [], wildcard: [] };
|
||||||
info.challenges = obj;
|
info.challenges = obj;
|
||||||
|
|
||||||
var $httpList = $qs('.js-acme-http');
|
var $httpList = $qs(".js-acme-http");
|
||||||
var $dnsList = $qs('.js-acme-dns');
|
var $dnsList = $qs(".js-acme-dns");
|
||||||
var $wildList = $qs('.js-acme-wildcard');
|
var $wildList = $qs(".js-acme-wildcard");
|
||||||
var httpTpl = $httpList.innerHTML;
|
var httpTpl = $httpList.innerHTML;
|
||||||
var dnsTpl = $dnsList.innerHTML;
|
var dnsTpl = $dnsList.innerHTML;
|
||||||
var wildTpl = $wildList.innerHTML;
|
var wildTpl = $wildList.innerHTML;
|
||||||
$httpList.innerHTML = '';
|
$httpList.innerHTML = "";
|
||||||
$dnsList.innerHTML = '';
|
$dnsList.innerHTML = "";
|
||||||
$wildList.innerHTML = '';
|
$wildList.innerHTML = "";
|
||||||
|
|
||||||
claims.forEach(function(claim) {
|
claims.forEach(function(claim) {
|
||||||
//#console.log("claims[i]", claim);
|
//#console.log("claims[i]", claim);
|
||||||
|
@ -302,15 +383,15 @@
|
||||||
claim.challenges.forEach(function(c) {
|
claim.challenges.forEach(function(c) {
|
||||||
var auth = c;
|
var auth = c;
|
||||||
var data = {
|
var data = {
|
||||||
type: c.type
|
type: c.type,
|
||||||
, hostname: hostname
|
hostname: hostname,
|
||||||
, url: c.url
|
url: c.url,
|
||||||
, token: c.token
|
token: c.token,
|
||||||
, httpPath: auth.challengeUrl
|
httpPath: auth.challengeUrl,
|
||||||
, httpAuth: auth.keyAuthorization
|
httpAuth: auth.keyAuthorization,
|
||||||
, dnsType: 'TXT'
|
dnsType: "TXT",
|
||||||
, dnsHost: auth.dnsHost
|
dnsHost: auth.dnsHost,
|
||||||
, dnsAnswer: auth.keyAuthorizationDigest
|
dnsAnswer: auth.keyAuthorizationDigest
|
||||||
};
|
};
|
||||||
//#console.log("claims[i].challenge", data);
|
//#console.log("claims[i].challenge", data);
|
||||||
|
|
||||||
|
@ -318,26 +399,36 @@
|
||||||
if (claim.wildcard) {
|
if (claim.wildcard) {
|
||||||
obj.wildcard.push(data);
|
obj.wildcard.push(data);
|
||||||
$tpl.innerHTML = wildTpl;
|
$tpl.innerHTML = wildTpl;
|
||||||
$tpl.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
|
$tpl.querySelector(".js-acme-ver-txt-host").innerHTML =
|
||||||
$tpl.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
|
data.dnsHost;
|
||||||
|
$tpl.querySelector(".js-acme-ver-txt-value").innerHTML =
|
||||||
|
data.dnsAnswer;
|
||||||
$wildList.appendChild($tpl);
|
$wildList.appendChild($tpl);
|
||||||
} else if (obj[data.type]) {
|
} else if (obj[data.type]) {
|
||||||
|
|
||||||
obj[data.type].push(data);
|
obj[data.type].push(data);
|
||||||
|
|
||||||
if ('dns-01' === data.type) {
|
if ("dns-01" === data.type) {
|
||||||
$tpl.innerHTML = dnsTpl;
|
$tpl.innerHTML = dnsTpl;
|
||||||
$tpl.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
|
$tpl.querySelector(".js-acme-ver-txt-host").innerHTML =
|
||||||
$tpl.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
|
data.dnsHost;
|
||||||
|
$tpl.querySelector(".js-acme-ver-txt-value").innerHTML =
|
||||||
|
data.dnsAnswer;
|
||||||
$dnsList.appendChild($tpl);
|
$dnsList.appendChild($tpl);
|
||||||
} else if ('http-01' === data.type) {
|
} else if ("http-01" === data.type) {
|
||||||
$tpl.innerHTML = httpTpl;
|
$tpl.innerHTML = httpTpl;
|
||||||
$tpl.querySelector(".js-acme-ver-file-location").innerHTML = data.httpPath.split("/").slice(-1);
|
$tpl.querySelector(
|
||||||
$tpl.querySelector(".js-acme-ver-content").innerHTML = data.httpAuth;
|
".js-acme-ver-file-location"
|
||||||
$tpl.querySelector(".js-acme-ver-uri").innerHTML = data.httpPath;
|
).innerHTML = data.httpPath.split("/").slice(-1);
|
||||||
|
$tpl.querySelector(".js-acme-ver-content").innerHTML =
|
||||||
|
data.httpAuth;
|
||||||
|
$tpl.querySelector(".js-acme-ver-uri").innerHTML =
|
||||||
|
data.httpPath;
|
||||||
$tpl.querySelector(".js-download-verify-link").href =
|
$tpl.querySelector(".js-download-verify-link").href =
|
||||||
"data:text/octet-stream;base64," + window.btoa(data.httpAuth);
|
"data:text/octet-stream;base64," +
|
||||||
$tpl.querySelector(".js-download-verify-link").download = data.httpPath.split("/").slice(-1);
|
window.btoa(data.httpAuth);
|
||||||
|
$tpl.querySelector(
|
||||||
|
".js-download-verify-link"
|
||||||
|
).download = data.httpPath.split("/").slice(-1);
|
||||||
$httpList.appendChild($tpl);
|
$httpList.appendChild($tpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,29 +438,36 @@
|
||||||
// hide wildcard if no wildcard
|
// hide wildcard if no wildcard
|
||||||
// hide http-01 and dns-01 if only wildcard
|
// hide http-01 and dns-01 if only wildcard
|
||||||
if (!obj.wildcard.length) {
|
if (!obj.wildcard.length) {
|
||||||
$qs('.js-acme-wildcard-challenges').hidden = true;
|
$qs(".js-acme-wildcard-challenges").hidden = true;
|
||||||
}
|
}
|
||||||
if (!obj['http-01'].length) {
|
if (!obj["http-01"].length) {
|
||||||
$qs('.js-acme-challenges').hidden = true;
|
$qs(".js-acme-challenges").hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info("[housekeeping] challenges", info.challenges);
|
console.info("[housekeeping] challenges", info.challenges);
|
||||||
|
|
||||||
updateChallengeType();
|
updateChallengeType();
|
||||||
return steps[i]();
|
return steps[i]();
|
||||||
}).catch(function (err) {
|
})
|
||||||
|
.catch(function(err) {
|
||||||
if (err.detail || err.urn) {
|
if (err.detail || err.urn) {
|
||||||
console.error("(Probably) User Error:");
|
console.error("(Probably) User Error:");
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return newAlert("There was an error, probably with your email or domain:\n" + err.message);
|
return newAlert(
|
||||||
|
"There was an error, probably with your email or domain:\n" +
|
||||||
|
err.message
|
||||||
|
);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
}).catch(function (err) {
|
})
|
||||||
console.error('Step \'\' Error:');
|
.catch(function(err) {
|
||||||
|
console.error("Step '' Error:");
|
||||||
console.error(err, err.stack);
|
console.error(err, err.stack);
|
||||||
return newAlert("An error happened (but it's not your fault)."
|
return newAlert(
|
||||||
+ " Email aj@rootprojects.org to let him know that 'order and get challenges' failed.");
|
"An error happened (but it's not your fault)." +
|
||||||
|
" Email aj@rootprojects.org to let him know that 'order and get challenges' failed."
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,14 +475,14 @@
|
||||||
console.info("\n3. Present challenge options");
|
console.info("\n3. Present challenge options");
|
||||||
updateProgress(1);
|
updateProgress(1);
|
||||||
hideForms();
|
hideForms();
|
||||||
$qs('.js-acme-form-challenges').hidden = false;
|
$qs(".js-acme-form-challenges").hidden = false;
|
||||||
};
|
};
|
||||||
steps[3].submit = function() {
|
steps[3].submit = function() {
|
||||||
console.info("[submit] 3. Fulfill challenges, fetch certificate");
|
console.info("[submit] 3. Fulfill challenges, fetch certificate");
|
||||||
|
|
||||||
var challengePriority = [ 'dns-01' ];
|
var challengePriority = ["dns-01"];
|
||||||
if ('http-01' === $qs('.js-acme-challenge-type:checked').value) {
|
if ("http-01" === $qs(".js-acme-challenge-type:checked").value) {
|
||||||
challengePriority.unshift('http-01');
|
challengePriority.unshift("http-01");
|
||||||
}
|
}
|
||||||
console.info("[challenge] selected ", challengePriority[0]);
|
console.info("[challenge] selected ", challengePriority[0]);
|
||||||
|
|
||||||
|
@ -396,32 +494,34 @@
|
||||||
// info.order.claims.push(...)
|
// info.order.claims.push(...)
|
||||||
// TODO warn about wait-time if DNS
|
// TODO warn about wait-time if DNS
|
||||||
return getServerKeypair().then(function(serverJwk) {
|
return getServerKeypair().then(function(serverJwk) {
|
||||||
return acme.orders.complete({
|
return acme.orders
|
||||||
account: info.account
|
.complete({
|
||||||
, accountKeypair: { privateKeyJwk: jwk }
|
account: info.account,
|
||||||
, order: info.order
|
accountKeypair: { privateKeyJwk: jwk },
|
||||||
, domains: info.domains
|
order: info.order,
|
||||||
, domainKeypair: { privateKeyJwk: serverJwk }
|
domains: info.domains,
|
||||||
, challengePriority: challengePriority
|
domainKeypair: { privateKeyJwk: serverJwk },
|
||||||
, challenges: false
|
challengePriority: challengePriority,
|
||||||
, onChallengeStatus: function (details) {
|
challenges: false,
|
||||||
$qs('.js-challenge-responses').hidden = false;
|
onChallengeStatus: function(details) {
|
||||||
$qs('.js-challenge-response-type').innerText = details.type;
|
$qs(".js-challenge-responses").hidden = false;
|
||||||
$qs('.js-challenge-response-status').innerText = details.status;
|
$qs(".js-challenge-response-type").innerText = details.type;
|
||||||
$qs('.js-challenge-response-altname').innerText = details.altname;
|
$qs(".js-challenge-response-status").innerText = details.status;
|
||||||
|
$qs(".js-challenge-response-altname").innerText = details.altname;
|
||||||
}
|
}
|
||||||
}).then(function (certs) {
|
})
|
||||||
|
.then(function(certs) {
|
||||||
return Keypairs.export({ jwk: serverJwk }).then(function(keyPem) {
|
return Keypairs.export({ jwk: serverJwk }).then(function(keyPem) {
|
||||||
console.info('WINNING!');
|
console.info("WINNING!");
|
||||||
console.info(certs);
|
console.info(certs);
|
||||||
$qs('#js-fullchain').innerHTML = [
|
$qs("#js-fullchain").innerHTML = [
|
||||||
certs.cert.trim() + "\n"
|
certs.cert.trim() + "\n",
|
||||||
, certs.chain + "\n"
|
certs.chain + "\n"
|
||||||
].join("\n");
|
].join("\n");
|
||||||
$qs("#js-download-fullchain-link").href =
|
$qs("#js-download-fullchain-link").href =
|
||||||
"data:text/octet-stream;base64," + window.btoa(certs);
|
"data:text/octet-stream;base64," + window.btoa(certs);
|
||||||
|
|
||||||
$qs('#js-privkey').innerHTML = keyPem;
|
$qs("#js-privkey").innerHTML = keyPem;
|
||||||
$qs("#js-download-privkey-link").href =
|
$qs("#js-download-privkey-link").href =
|
||||||
"data:text/octet-stream;base64," + window.btoa(keyPem);
|
"data:text/octet-stream;base64," + window.btoa(keyPem);
|
||||||
return submitForm();
|
return submitForm();
|
||||||
|
@ -433,48 +533,47 @@
|
||||||
|
|
||||||
// spinner
|
// spinner
|
||||||
steps[4] = function() {
|
steps[4] = function() {
|
||||||
console.info('\n4. Show loading spinner');
|
console.info("\n4. Show loading spinner");
|
||||||
updateProgress(1);
|
updateProgress(1);
|
||||||
hideForms();
|
hideForms();
|
||||||
$qs('.js-acme-form-poll').hidden = false;
|
$qs(".js-acme-form-poll").hidden = false;
|
||||||
};
|
};
|
||||||
steps[4].submit = function() {
|
steps[4].submit = function() {
|
||||||
console.info('[submit] 4. Order complete');
|
console.info("[submit] 4. Order complete");
|
||||||
|
|
||||||
return steps[i]();
|
return steps[i]();
|
||||||
};
|
};
|
||||||
|
|
||||||
steps[5] = function() {
|
steps[5] = function() {
|
||||||
console.info('\n5. Present certificates (yay!)');
|
console.info("\n5. Present certificates (yay!)");
|
||||||
updateProgress(2);
|
updateProgress(2);
|
||||||
hideForms();
|
hideForms();
|
||||||
$qs('.js-acme-form-download').hidden = false;
|
$qs(".js-acme-form-download").hidden = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$qsa('.js-acme-api-type').forEach(function ($el) {
|
$qsa(".js-acme-api-type").forEach(function($el) {
|
||||||
$el.addEventListener('change', updateApiType);
|
$el.addEventListener("change", updateApiType);
|
||||||
});
|
});
|
||||||
updateApiType();
|
updateApiType();
|
||||||
|
|
||||||
$qsa('.js-acme-form').forEach(function ($el) {
|
$qsa(".js-acme-form").forEach(function($el) {
|
||||||
$el.addEventListener('submit', function (ev) {
|
$el.addEventListener("submit", function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
return submitForm(ev);
|
return submitForm(ev);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$qsa('.js-acme-challenge-type').forEach(function ($el) {
|
$qsa(".js-acme-challenge-type").forEach(function($el) {
|
||||||
$el.addEventListener('change', updateChallengeType);
|
$el.addEventListener("change", updateChallengeType);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var params = new URLSearchParams(window.location.search);
|
var params = new URLSearchParams(window.location.search);
|
||||||
var apiType = params.get('acme-api-type') || "staging-v02";
|
var apiType = params.get("acme-api-type") || "staging-v02";
|
||||||
if (params.has('acme-domains')) {
|
if (params.has("acme-domains")) {
|
||||||
$qs('.js-acme-domains').value = params.get('acme-domains');
|
$qs(".js-acme-domains").value = params.get("acme-domains");
|
||||||
|
|
||||||
$qsa('.js-acme-api-type').forEach(function(ele) {
|
$qsa(".js-acme-api-type").forEach(function(ele) {
|
||||||
if (ele.value === apiType) {
|
if (ele.value === apiType) {
|
||||||
ele.checked = true;
|
ele.checked = true;
|
||||||
}
|
}
|
||||||
|
@ -489,16 +588,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
$qs('body').hidden = false;
|
$qs("body").hidden = false;
|
||||||
|
|
||||||
// in the background
|
// in the background
|
||||||
info.cryptoCheck = testKeypairSupport().then(function () {
|
info.cryptoCheck = testKeypairSupport()
|
||||||
|
.then(function() {
|
||||||
console.info("[crypto] self-check: passed");
|
console.info("[crypto] self-check: passed");
|
||||||
}).catch(function (err) {
|
})
|
||||||
console.error('[crypto] could not use either RSA nor EC.');
|
.catch(function(err) {
|
||||||
|
console.error("[crypto] could not use either RSA nor EC.");
|
||||||
console.error(err);
|
console.error(err);
|
||||||
window.alert("Generating secure certificates requires a browser with cryptography support."
|
window.alert(
|
||||||
+ "Please consider a recent version of Chrome, Firefox, or Safari.");
|
"Generating secure certificates requires a browser with cryptography support." +
|
||||||
|
"Please consider a recent version of Chrome, Firefox, or Safari."
|
||||||
|
);
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
}());
|
})();
|
||||||
|
|
|
@ -15,7 +15,8 @@ a {
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=email], input[type=text] {
|
input[type="email"],
|
||||||
|
input[type="text"] {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
padding: 0.444444444em 0.888889em;
|
padding: 0.444444444em 0.888889em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -89,7 +90,6 @@ pre {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
=: block font-size: ;
|
|
||||||
top: 139%;
|
top: 139%;
|
||||||
font-size: 0.722222222em;
|
font-size: 0.722222222em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -111,7 +111,8 @@ pre {
|
||||||
padding: 1.6em 2.9333em 1.6em 1.6em;
|
padding: 1.6em 2.9333em 1.6em 1.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.js-progress-step-complete > .circle, .js-progress-step-started > .circle {
|
.js-progress-step-complete > .circle,
|
||||||
|
.js-progress-step-started > .circle {
|
||||||
background-color: #5bc17f;
|
background-color: #5bc17f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,28 +128,29 @@ pre {
|
||||||
padding: 1em 0;
|
padding: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox] {
|
.checkbox-array input[type="checkbox"] {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox] ~ .icon-checked-box {
|
.checkbox-array input[type="checkbox"] ~ .icon-checked-box {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox] ~ .icon-unchecked-box {
|
.checkbox-array input[type="checkbox"] ~ .icon-unchecked-box {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox]:checked ~ .icon-checked-box {
|
.checkbox-array input[type="checkbox"]:checked ~ .icon-checked-box {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox]:checked ~ .icon-unchecked-box {
|
.checkbox-array input[type="checkbox"]:checked ~ .icon-unchecked-box {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array .icon-checked-box, .checkbox-array .icon-unchecked-box {
|
.checkbox-array .icon-checked-box,
|
||||||
|
.checkbox-array .icon-unchecked-box {
|
||||||
width: 1.333333333em;
|
width: 1.333333333em;
|
||||||
fill: #5bc17f;
|
fill: #5bc17f;
|
||||||
margin-right: 0.666666667em;
|
margin-right: 0.666666667em;
|
||||||
|
@ -161,7 +163,8 @@ pre {
|
||||||
margin: 0.4em 0;
|
margin: 0.4em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-array input[type=checkbox]:focus ~ .icon-checked-box, .checkbox-array input[type=checkbox]:focus ~ .icon-unchecked-box {
|
.checkbox-array input[type="checkbox"]:focus ~ .icon-checked-box,
|
||||||
|
.checkbox-array input[type="checkbox"]:focus ~ .icon-unchecked-box {
|
||||||
background: #5bc17f52;
|
background: #5bc17f52;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +195,7 @@ pre {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbed-selector input[type=radio] {
|
.tabbed-selector input[type="radio"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +225,13 @@ pre {
|
||||||
border-bottom: solid #d9d9d9 1px;
|
border-bottom: solid #d9d9d9 1px;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: linear-gradient(45deg, #f7f7f7 0%,#f7f7f7 50%,#ffffff 50%,#ffffff 100%);
|
background: linear-gradient(
|
||||||
|
45deg,
|
||||||
|
#f7f7f7 0%,
|
||||||
|
#f7f7f7 50%,
|
||||||
|
#ffffff 50%,
|
||||||
|
#ffffff 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-ver-info-header {
|
.file-ver-info-header {
|
||||||
|
@ -256,8 +265,6 @@ pre {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.cert-download-container {
|
.cert-download-container {
|
||||||
margin: 0 -31%;
|
margin: 0 -31%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
144
index.html
144
index.html
|
@ -1,72 +1,137 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Greenlock™</title>
|
<title>Greenlock™</title>
|
||||||
<meta property="og:image" content="https://greenlock.domains/img/greenlock-mark-400x400.png" />
|
<meta
|
||||||
<link href="styles/main.css" rel="stylesheet">
|
property="og:image"
|
||||||
|
content="https://greenlock.domains/img/greenlock-mark-400x400.png"
|
||||||
|
/>
|
||||||
|
<link href="styles/main.css" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: "Source Sans Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
|
src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
url(./fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||||
|
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: "Source Sans Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2');
|
src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
url(./fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2)
|
||||||
|
format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||||
|
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||||
|
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="preload" href="./app/fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2" as="font" crossorigin="anonymous">
|
<link
|
||||||
<link rel="preload" href="./app/fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2" as="font" crossorigin="anonymous">
|
rel="preload"
|
||||||
<link rel="prefetch" href="./app/fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2" as="font" crossorigin="anonymous">
|
href="./app/fonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2"
|
||||||
<link rel="prefetch" href="./app/js/bluecrypt-acme.js" as="script">
|
as="font"
|
||||||
<link rel="prefetch" href="./app/js/greenlock.js" as="script">
|
crossorigin="anonymous"
|
||||||
<link rel="prefetch" href="./js/app.js" as="script">
|
/>
|
||||||
|
<link
|
||||||
|
rel="preload"
|
||||||
|
href="./app/fonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2"
|
||||||
|
as="font"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="prefetch"
|
||||||
|
href="./app/fonts/HI_SiYsKILxRpg3hIP6sJ7fM7PqlPevW.woff2"
|
||||||
|
as="font"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<link rel="prefetch" href="./app/js/bluecrypt-acme.js" as="script" />
|
||||||
|
<link rel="prefetch" href="./app/js/greenlock.js" as="script" />
|
||||||
|
<link rel="prefetch" href="./js/app.js" as="script" />
|
||||||
</head>
|
</head>
|
||||||
<body class="js-app-ready">
|
<body class="js-app-ready">
|
||||||
<script>
|
<script>
|
||||||
document.querySelector('body').classList.remove("js-app-ready");
|
document.querySelector("body").classList.remove("js-app-ready");
|
||||||
</script>
|
</script>
|
||||||
<div class="column-container wide">
|
<div class="column-container wide">
|
||||||
|
|
||||||
<div class="column-row">
|
<div class="column-row">
|
||||||
<img src="img/greenlock-146.png">
|
<img alt="Greenlock logo" src="img/greenlock-146.png" />
|
||||||
</div>
|
</div>
|
||||||
<div class="column-row">
|
<div class="column-row">
|
||||||
<h1>Get the green lock for your website</h1>
|
<h1>Get the green lock for your website</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="column-row">
|
<div class="column-row">
|
||||||
<div class="js-javascript-warning">
|
<div class="js-javascript-warning">
|
||||||
Greenlock will process the CSR in the browser and request the certificates directly from letsencrypt.org.
|
Greenlock will process the CSR in the browser and request the
|
||||||
Please enable Javascript before continuing.
|
certificates directly from letsencrypt.org. Please enable Javascript
|
||||||
|
before continuing.
|
||||||
</div>
|
</div>
|
||||||
<form id="js-acme-form" action="./app/" method="GET">
|
<form id="js-acme-form" action="./app/" method="GET">
|
||||||
<div class="domain-psuedo-input">
|
<div class="domain-psuedo-input">
|
||||||
<span class="secure-green">Secure</span> | <span class="secure-green">https:</span>//<input aria-label="domains to secure" id="acme-domains" type="text" name="acme-domains" placeholder="Your domain name" required>
|
<span class="secure-green">Secure</span> |
|
||||||
|
<span class="secure-green">https:</span>//<input
|
||||||
|
aria-label="domains to secure"
|
||||||
|
id="acme-domains"
|
||||||
|
type="text"
|
||||||
|
name="acme-domains"
|
||||||
|
placeholder="Your domain name"
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit">Go</button>
|
<button type="submit">Go</button>
|
||||||
<div class="domain-subtext">Domain, subdomain, or wildcard domain</div>
|
<div class="domain-subtext">
|
||||||
|
Domain, subdomain, or wildcard domain
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="acme-advanced-fields">
|
<div class="acme-advanced-fields">
|
||||||
<label><input name="acme-api-type" type="radio" value="v02" checked required>
|
<label
|
||||||
|
><input
|
||||||
|
name="acme-api-type"
|
||||||
|
type="radio"
|
||||||
|
value="v02"
|
||||||
|
checked
|
||||||
|
required
|
||||||
|
/>
|
||||||
Production
|
Production
|
||||||
</label>
|
</label>
|
||||||
<label><input name="acme-api-type" type="radio" value="staging-v02" required>
|
<label
|
||||||
Testing</label>
|
><input
|
||||||
<input id="js-acme-api-url" type="url" placeholder="ACME directory url">
|
name="acme-api-type"
|
||||||
<br>
|
type="radio"
|
||||||
|
value="staging-v02"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
Testing</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="js-acme-api-url"
|
||||||
|
type="url"
|
||||||
|
placeholder="ACME directory url"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
API Compatibility: Let's Encrypt v2 / ACME draft 15
|
API Compatibility: Let's Encrypt v2 / ACME draft 15
|
||||||
<div>
|
<div>
|
||||||
<br>
|
<br />
|
||||||
A <a href="https://rootprojects.org/" target="_blank">Root</a> Project
|
A
|
||||||
| <a href="https://git.coolaj86.com/coolaj86/greenlock.html" target="_blank">View Source</a> (git)
|
<a href="https://rootprojects.org/" target="_blank">Root</a>
|
||||||
| <a href="https://rootprojects.org/legal/#terms" target="_blank">Terms of Service</a>
|
Project |
|
||||||
| <a href="https://rootprojects.org/legal/#privacy" target="_blank">Privacy Policy</a>
|
<a
|
||||||
|
href="https://git.coolaj86.com/coolaj86/greenlock.html"
|
||||||
|
target="_blank"
|
||||||
|
>View Source</a
|
||||||
|
>
|
||||||
|
(git) |
|
||||||
|
<a href="https://rootprojects.org/legal/#terms" target="_blank"
|
||||||
|
>Terms of Service</a
|
||||||
|
>
|
||||||
|
|
|
||||||
|
<a href="https://rootprojects.org/legal/#privacy" target="_blank"
|
||||||
|
>Privacy Policy</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -74,7 +139,9 @@
|
||||||
<div class="column-row">
|
<div class="column-row">
|
||||||
<div class="why-you-need">
|
<div class="why-you-need">
|
||||||
<h2>Why you need HTTPS</h2>
|
<h2>Why you need HTTPS</h2>
|
||||||
SSL Certificates are required for secure login, accepting payments, and for browsers like Google Chrome to stop showing security warnings to your users.
|
SSL Certificates are required for secure login, accepting payments,
|
||||||
|
and for browsers like Google Chrome to stop showing security warnings
|
||||||
|
to your users.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- or
|
<!-- or
|
||||||
|
@ -86,13 +153,18 @@
|
||||||
<script src="./js/app.js"></script>
|
<script src="./js/app.js"></script>
|
||||||
|
|
||||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-118745161-2"></script>
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id=UA-118745161-2"
|
||||||
|
></script>
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag(){dataLayer.push(arguments);}
|
function gtag() {
|
||||||
gtag('js', new Date());
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
|
||||||
gtag('config', 'UA-118745161-2');
|
gtag("config", "UA-118745161-2");
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
33
js/app.js
33
js/app.js
|
@ -1,32 +1,39 @@
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
var $qs = function (s) { return window.document.querySelector(s); };
|
var $qs = function(s) {
|
||||||
|
return window.document.querySelector(s);
|
||||||
|
};
|
||||||
|
|
||||||
$qs('.js-javascript-warning').hidden = true;
|
$qs(".js-javascript-warning").hidden = true;
|
||||||
|
|
||||||
var apiUrl = 'https://acme-{{env}}.api.letsencrypt.org/directory';
|
var apiUrl = "https://acme-{{env}}.api.letsencrypt.org/directory";
|
||||||
|
|
||||||
function updateApiType() {
|
function updateApiType() {
|
||||||
var formData = new FormData($qs("#js-acme-form"));
|
var formData = new FormData($qs("#js-acme-form"));
|
||||||
|
|
||||||
console.log('ACME api type radio:');
|
console.log("ACME api type radio:");
|
||||||
|
|
||||||
var value = formData.get("acme-api-type");
|
var value = formData.get("acme-api-type");
|
||||||
$qs('#js-acme-api-url').value = apiUrl.replace(/{{env}}/g, value);
|
$qs("#js-acme-api-url").value = apiUrl.replace(/{{env}}/g, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$qs('#js-acme-form').addEventListener('change', updateApiType);
|
$qs("#js-acme-form").addEventListener("change", updateApiType);
|
||||||
//$qs('#js-acme-form').addEventListener('submit', prettyRedirect);
|
//$qs('#js-acme-form').addEventListener('submit', prettyRedirect);
|
||||||
|
|
||||||
updateApiType();
|
updateApiType();
|
||||||
try {
|
try {
|
||||||
document.fonts.load().then(function() {
|
document.fonts
|
||||||
$qs('body').classList.add("js-app-ready");
|
.load()
|
||||||
}).catch(function(e) {
|
.then(function() {
|
||||||
$qs('body').classList.add("js-app-ready");
|
$qs("body").classList.add("js-app-ready");
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
|
$qs("body").classList.add("js-app-ready");
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setTimeout(function() {$qs('body').classList.add("js-app-ready");}, 200);
|
setTimeout(function() {
|
||||||
|
$qs("body").classList.add("js-app-ready");
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
}());
|
})();
|
||||||
|
|
364
legal.html
364
legal.html
|
@ -1,16 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Root Legal</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
<h1>Greetings!</h1>
|
<h1>Greetings!</h1>
|
||||||
|
|
||||||
<p>I, AJ ONeal, am not a big fan of legalize, but I am a fan of communicating
|
<p>
|
||||||
clearly. I hope that this accomplish both defining some legal boundaries as well
|
I, AJ ONeal, am not a big fan of legalize, but I am a fan of communicating
|
||||||
as communicating in a friendly and clear way, at least to the degree that suits
|
clearly. I hope that this accomplish both defining some legal boundaries
|
||||||
our needs for the current stage of our products and services.
|
as well as communicating in a friendly and clear way, at least to the
|
||||||
|
degree that suits our needs for the current stage of our products and
|
||||||
|
services.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>This is important because it is our intent to create sustainable open source
|
<p>
|
||||||
projects, which means that we do want to create brand value, grow community,
|
This is important because it is our intent to create sustainable open
|
||||||
and, eventually, be able to work full time on creating more great software and services.
|
source projects, which means that we do want to create brand value, grow
|
||||||
|
community, and, eventually, be able to work full time on creating more
|
||||||
|
great software and services.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If you'd like to contact me, especially if you feel that I (or we) have made
|
<p>
|
||||||
a mistake in how we operate, please do so:
|
If you'd like to contact me, especially if you feel that I (or we) have
|
||||||
|
made a mistake in how we operate, please do so:
|
||||||
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="mailto:coolaj86@gmail.com">coolaj86@gmail.com</a></li>
|
<li><a href="mailto:coolaj86@gmail.com">coolaj86@gmail.com</a></li>
|
||||||
|
@ -19,7 +33,7 @@ a mistake in how we operate, please do so:
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h1>Contents</h1>
|
<h1>Contents</h1>
|
||||||
<p>Here's what I've worked through so far:
|
<p>Here's what I've worked through so far:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#greenlock">Greelock Domains</a></li>
|
<li><a href="#greenlock">Greelock Domains</a></li>
|
||||||
|
@ -31,171 +45,271 @@ a mistake in how we operate, please do so:
|
||||||
|
|
||||||
<h1 id="greenlock">Greenlock Domains™</h1>
|
<h1 id="greenlock">Greenlock Domains™</h1>
|
||||||
|
|
||||||
<p>Greenlock Domains is a service provided by
|
<p>
|
||||||
<em><a href="https://coolaj86.com">AJ</a>, Brian,
|
Greenlock Domains is a service provided by
|
||||||
<a href="https://jshaver.net">John</a>, & Josh</em>
|
<em
|
||||||
(collectively <a href="https://therootcompany.com">Root</a>)
|
><a href="https://coolaj86.com">AJ</a>, Brian,
|
||||||
for automated TLS, SSL, and HTTPS.
|
<a href="https://jshaver.net">John</a>, & Josh</em
|
||||||
|
>
|
||||||
|
(collectively <a href="https://therootcompany.com">Root</a>) for automated
|
||||||
|
TLS, SSL, and HTTPS.
|
||||||
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://greenlock.domains" target="_blank">
|
<li>
|
||||||
https://greenlock.domains</a></li>
|
<a href="https://greenlock.domains" target="_blank">
|
||||||
|
https://greenlock.domains</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><a href="https://git.coolaj86.com/coolaj86/greenlock-express.js" target="_blank">
|
<li>
|
||||||
https://git.coolaj86.com/coolaj86/greenlock-express.js</a></li>
|
<a
|
||||||
|
href="https://git.coolaj86.com/coolaj86/greenlock-express.js"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
https://git.coolaj86.com/coolaj86/greenlock-express.js</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><a href="https://git.coolaj86.com/coolaj86/greenlock.js" target="_blank">
|
<li>
|
||||||
https://git.coolaj86.com/coolaj86/greenlock.js</a></li>
|
<a
|
||||||
|
href="https://git.coolaj86.com/coolaj86/greenlock.js"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
https://git.coolaj86.com/coolaj86/greenlock.js</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><a href="https://git.coolaj86.com/coolaj86/greenlock.html" target="_blank">
|
<li>
|
||||||
https://git.coolaj86.com/coolaj86/greenlock.html</a></li>
|
<a
|
||||||
|
href="https://git.coolaj86.com/coolaj86/greenlock.html"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
https://git.coolaj86.com/coolaj86/greenlock.html</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Greenlock Domains is an important product / service combo to us
|
<p>
|
||||||
because it's a huge milestone on the path to a more decentralized web.
|
Greenlock Domains is an important product / service combo to us because
|
||||||
We believe in <em>ownership</em> and <em>control</em> and we're
|
it's a huge milestone on the path to a more decentralized web. We believe
|
||||||
building a <a href="https://therootcompany.com">Home Server</a>
|
in
|
||||||
because we envision a world in which everyone is empowered to make
|
<em>ownership</em> and <em>control</em> and we're building a
|
||||||
the choice of whether to rent or own their stuff.
|
<a href="https://therootcompany.com">Home Server</a> because we envision a
|
||||||
|
world in which everyone is empowered to make the choice of whether to rent
|
||||||
|
or own their stuff.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If we don't do this, well, with the way the cloud is headed,
|
<p>
|
||||||
renting may be the only option in the future.
|
If we don't do this, well, with the way the cloud is headed, renting may
|
||||||
|
be the only option in the future.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>We need <em>Root</em> because we want ownership.
|
<p>We need <em>Root</em> because we want ownership.</p>
|
||||||
|
|
||||||
<p>If at any time you feel that any of our messaging or practices
|
<p>
|
||||||
are in conflict with our mission or these values, please let us know.
|
If at any time you feel that any of our messaging or practices are in
|
||||||
|
conflict with our mission or these values, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h1 id="licensing">Licensing</h1>
|
<h1 id="licensing">Licensing</h1>
|
||||||
|
|
||||||
<p>Each of our products comes with its own LICENSE file and the license(s)
|
<p>
|
||||||
|
Each of our products comes with its own LICENSE file and the license(s)
|
||||||
may alse be in some sort of manifest file (such as package.json).
|
may alse be in some sort of manifest file (such as package.json).
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>We typically use the MIT and Apache-2.0 licenses for libraries that we
|
<p>
|
||||||
|
We typically use the MIT and Apache-2.0 licenses for libraries that we
|
||||||
actively want others to copy, modify, use and redistribute.
|
actively want others to copy, modify, use and redistribute.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>We typically use ISC and MPL-2.0 with products for which we're a little more
|
<p>
|
||||||
concerned about branding or about which we have particularly strong opinions.
|
We typically use ISC and MPL-2.0 with products for which we're a little
|
||||||
|
more concerned about branding or about which we have particularly strong
|
||||||
|
opinions.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>Although we do keep some of our software proprietary and we do use trademarks,
|
<p>
|
||||||
because we believe in empowerment and choice we do our best to provide usable
|
Although we do keep some of our software proprietary and we do use
|
||||||
self-service forms of our products and services for personal use.
|
trademarks, because we believe in empowerment and choice we do our best to
|
||||||
|
provide usable self-service forms of our products and services for
|
||||||
|
personal use.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If at any time you feel that our Licensing is in conflict with our mission or values,
|
<p>
|
||||||
please let us know.
|
If at any time you feel that our Licensing is in conflict with our mission
|
||||||
|
or values, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h1 id="terms">Terms of Service</h1>
|
<h1 id="terms">Terms of Service</h1>
|
||||||
|
|
||||||
<p>We want to make the world a better place.
|
<p>
|
||||||
Everyone has a different definition of what "a better place" means,
|
We want to make the world a better place. Everyone has a different
|
||||||
so the purpose of our terms is to rule out some things that
|
definition of what "a better place" means, so the purpose of our terms is
|
||||||
we think makes the world (and particularly our world) a worse place:
|
to rule out some things that we think makes the world (and particularly
|
||||||
|
our world) a worse place:
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>You agree that you will use the Greenlock™ service, code, libraries,
|
<p>
|
||||||
documentation, etc (provided by <a href="#greenlock">us</a>)
|
You agree that you will use the Greenlock™ service, code, libraries,
|
||||||
primarily for securing network connections for yourself, your customers,
|
documentation, etc (provided by <a href="#greenlock">us</a>) primarily for
|
||||||
on your and your customer's devices on internets, intranets, and... other nets.
|
securing network connections for yourself, your customers, on your and
|
||||||
|
your customer's devices on internets, intranets, and... other nets.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>You agree that you will take reasonable measures to keep up-to-date with security
|
<p>
|
||||||
releases.
|
You agree that you will take reasonable measures to keep up-to-date with
|
||||||
|
security releases.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>You agree to not use our products or services in a way that would cause unusual
|
<p>
|
||||||
or undue burden on our servers or services, our partners servers or services, or our
|
You agree to not use our products or services in a way that would cause
|
||||||
customers servers or services, or in a way that harms or misrepresents the reputation
|
unusual or undue burden on our servers or services, our partners servers
|
||||||
or brand value (including causing brand confusion) of the aforementioned parties
|
or services, or our customers servers or services, or in a way that harms
|
||||||
(or really anybody).
|
or misrepresents the reputation or brand value (including causing brand
|
||||||
|
confusion) of the aforementioned parties (or really anybody).
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>This is not to say that you can't publicly have a negative opinion, but don't
|
<p>
|
||||||
bite the hand that feeds and don't be vicious or misrepresentative.
|
This is not to say that you can't publicly have a negative opinion, but
|
||||||
|
don't bite the hand that feeds and don't be vicious or misrepresentative.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If you have a use case that may be in violation of these terms (particularly
|
<p>
|
||||||
the part about undue burden), but you feel contributes to making the world a better
|
If you have a use case that may be in violation of these terms
|
||||||
place, we're here to help (assuming it also aligns with our values).
|
(particularly the part about undue burden), but you feel contributes to
|
||||||
Although it may not be appropriate to use our services, but perhaps we can help
|
making the world a better place, we're here to help (assuming it also
|
||||||
you with a solution based on our no-cost, low-cost or open source products.
|
aligns with our values). Although it may not be appropriate to use our
|
||||||
|
services, but perhaps we can help you with a solution based on our
|
||||||
|
no-cost, low-cost or open source products.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If at any time you feel that our Terms of Service are in conflict with our
|
<p>
|
||||||
|
If at any time you feel that our Terms of Service are in conflict with our
|
||||||
mission or values, please let us know.
|
mission or values, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h1 id="trademark">Trademark</h1>
|
<h1 id="trademark">Trademark</h1>
|
||||||
|
|
||||||
<p>"Greenlock" and the "green G lock" mark are Trademarks of
|
<p>
|
||||||
|
"Greenlock" and the "green G lock" mark are Trademarks of
|
||||||
<a href="https://coolaj86.com" target="_blank">AJ ONeal</a>.
|
<a href="https://coolaj86.com" target="_blank">AJ ONeal</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>We'll be coming out with a brand guide as to how you should use
|
<p>
|
||||||
the marks. In the meantime: don't change the proportions, colors
|
We'll be coming out with a brand guide as to how you should use the marks.
|
||||||
(excepting the case of greyscale and black and white).
|
In the meantime: don't change the proportions, colors (excepting the case
|
||||||
|
of greyscale and black and white).
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>It is appropriate to use the trademark in a way that promotes the
|
<p>
|
||||||
brand with proper attribution, linking to the official project repositories, etc.
|
It is appropriate to use the trademark in a way that promotes the brand
|
||||||
|
with proper attribution, linking to the official project repositories,
|
||||||
|
etc.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>It is appropriate use the name greenlock in a plugin for Greenlock™,
|
<p>
|
||||||
|
It is appropriate use the name greenlock in a plugin for Greenlock™,
|
||||||
as long as it is clear that it is a community contribution.
|
as long as it is clear that it is a community contribution.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If you create a "hard" fork of our code or any products or services,
|
<p>
|
||||||
you should give your fork its own name, and not use ours.
|
If you create a "hard" fork of our code or any products or services, you
|
||||||
That sound, we gladly welcome your suggestiosn and pull requests.
|
should give your fork its own name, and not use ours. That sound, we
|
||||||
|
gladly welcome your suggestiosn and pull requests.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If you mirror our code you should make it clear that it is a mirror
|
<p>
|
||||||
and link to the official repository.
|
If you mirror our code you should make it clear that it is a mirror and
|
||||||
in association with usand the disclose that you use Greenlock
|
link to the official repository. in association with usand the disclose
|
||||||
|
that you use Greenlock
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If at any time you feel that our Trademark policies are in conflict with our
|
<p>
|
||||||
values, please let us know.
|
If at any time you feel that our Trademark policies are in conflict with
|
||||||
|
our values, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h1 id="privacy">Privacy Policy</h1>
|
<h1 id="privacy">Privacy Policy</h1>
|
||||||
|
|
||||||
<p>What we collect and (more importantly) <em>Why</em>:
|
<p>What we collect and (more importantly) <em>Why</em>:</p>
|
||||||
|
|
||||||
<p><strong>Name</strong>:
|
<p><strong>Name</strong>:</p>
|
||||||
<p>In the cases that we collect your name, it's because we want to know how to address you.
|
<p>
|
||||||
All four of us want to be personable if and when we reach out.
|
In the cases that we collect your name, it's because we want to know how
|
||||||
|
to address you. All four of us want to be personable if and when we reach
|
||||||
|
out.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><strong>Email</strong>:
|
<p><strong>Email</strong>:</p>
|
||||||
<p>There are three main purposes for which we may use your email address:
|
<p>
|
||||||
|
There are three main purposes for which we may use your email address:
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>1. A one-time outreach to ask if you were able to do what you intended to do.
|
<p>
|
||||||
We want to make a great product. Although open source projects traditionally have
|
1. A one-time outreach to ask if you were able to do what you intended to
|
||||||
a <em>reactive</em> approach to communication (i.e. you file a bug and wait for a response),
|
do. We want to make a great product. Although open source projects
|
||||||
we believe that creating sustainable open source requires a <em>proactive</em> approach.
|
traditionally have a <em>reactive</em> approach to communication (i.e. you
|
||||||
|
file a bug and wait for a response), we believe that creating sustainable
|
||||||
|
open source requires a <em>proactive</em> approach.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>2. Security and legal notifications. It's important that we have a way to contact you
|
<p>
|
||||||
if we've made a mistake or discover a mistake that needs to be addressed. This
|
2. Security and legal notifications. It's important that we have a way to
|
||||||
may include vulnerabilities as well as mandatory upgrades (such as when a
|
contact you if we've made a mistake or discover a mistake that needs to be
|
||||||
significant change to the Let's Encrypt API is made). Making sure that our products
|
addressed. This may include vulnerabilities as well as mandatory upgrades
|
||||||
work and are secure aligns with our values and contributes to our brand identity.
|
(such as when a significant change to the Let's Encrypt API is made).
|
||||||
|
Making sure that our products work and are secure aligns with our values
|
||||||
|
and contributes to our brand identity.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>3. Opt-in updates. Many of you want to know when we have significant feature updates
|
<p>
|
||||||
or when we have something that we believe is really valuable to share. We've created an
|
3. Opt-in updates. Many of you want to know when we have significant
|
||||||
opt-in avenue for that. And you can always opt-out as well.
|
feature updates or when we have something that we believe is really
|
||||||
|
valuable to share. We've created an opt-in avenue for that. And you can
|
||||||
|
always opt-out as well.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><strong>Telemetry</strong>:
|
<p><strong>Telemetry</strong>:</p>
|
||||||
<p>We believe that the current open source model needs improvement - it often
|
<p>
|
||||||
relies heavily on large centralized platforms which aggregate a lot of user
|
We believe that the current open source model needs improvement - it often
|
||||||
information for the platform without appropriately targeting the relationship
|
relies heavily on large centralized platforms which aggregate a lot of
|
||||||
between authors and users of projcts (i.e. npm, github, etc). We believe that
|
user information for the platform without appropriately targeting the
|
||||||
making open source sustainable means a greater focus on empowering authors
|
relationship between authors and users of projcts (i.e. npm, github, etc).
|
||||||
and users. We've learned from other projects (Caddy, Heroku, and others) which
|
We believe that making open source sustainable means a greater focus on
|
||||||
use telemetry as part of a proactive approach to open source and we believe that
|
empowering authors and users. We've learned from other projects (Caddy,
|
||||||
it can be a great avenue for us to be proactive as well.
|
Heroku, and others) which use telemetry as part of a proactive approach to
|
||||||
|
open source and we believe that it can be a great avenue for us to be
|
||||||
|
proactive as well.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>We may use telemetry about operating system, browser, node version, code version,
|
<p>
|
||||||
and other system-level information to better understand how we can serve our users (you)
|
We may use telemetry about operating system, browser, node version, code
|
||||||
and proactively solve problems that we might not otherwise hear about. For example, if
|
version, and other system-level information to better understand how we
|
||||||
we see many page visits in a certain browser (or installs with a new version of node),
|
can serve our users (you) and proactively solve problems that we might not
|
||||||
but few successful registrations, we know that something is wrong.
|
otherwise hear about. For example, if we see many page visits in a certain
|
||||||
|
browser (or installs with a new version of node), but few successful
|
||||||
|
registrations, we know that something is wrong.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><strong>Other</strong>:
|
<p><strong>Other</strong>:</p>
|
||||||
<p>We also use Google Analytics on our web sites for basic functionality.
|
<p>
|
||||||
Other than that, nothing else comes to mind right now.
|
We also use Google Analytics on our web sites for basic functionality.
|
||||||
As we consider what we will do in the future, it will be measured against our mission and values.
|
Other than that, nothing else comes to mind right now. As we consider what
|
||||||
We never want to come across as spammy or forceful. We want to do things that help us build
|
we will do in the future, it will be measured against our mission and
|
||||||
our brand, acknowledge our customers; things that are proactive, and that
|
values. We never want to come across as spammy or forceful. We want to do
|
||||||
promote sustainable source.
|
things that help us build our brand, acknowledge our customers; things
|
||||||
|
that are proactive, and that promote sustainable source.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If at any time you feel that our Privacy policy is in conflict with our mission or values,
|
<p>
|
||||||
please let us know.
|
If at any time you feel that our Privacy policy is in conflict with our
|
||||||
|
mission or values, please let us know.
|
||||||
|
</p>
|
||||||
|
|
||||||
<br>
|
<br />
|
||||||
<br>
|
<br />
|
||||||
<p>Copyright 2018 AJ ONeal
|
<p>Copyright 2018 AJ ONeal</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -10,7 +10,7 @@ body {
|
||||||
margin-top: 5.777777778em;
|
margin-top: 5.777777778em;
|
||||||
min-height: 36em;
|
min-height: 36em;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: 'Source Sans Pro', sans-serif;
|
font-family: "Source Sans Pro", sans-serif;
|
||||||
font-stretch: normal;
|
font-stretch: normal;
|
||||||
line-height: 1.33;
|
line-height: 1.33;
|
||||||
letter-spacing: -0.4px;
|
letter-spacing: -0.4px;
|
||||||
|
@ -68,7 +68,7 @@ input#acme-domains:before {
|
||||||
|
|
||||||
.domain-psuedo-input {
|
.domain-psuedo-input {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: .6666667em;
|
margin-right: 0.6666667em;
|
||||||
border: solid #d9d9d9 1px;
|
border: solid #d9d9d9 1px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 0.44444444em;
|
padding: 0.44444444em;
|
||||||
|
@ -112,4 +112,3 @@ body.js-app-ready {
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
width: 30em;
|
width: 30em;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue