make Prettier™
This commit is contained in:
		
							parent
							
								
									137990002a
								
							
						
					
					
						commit
						513fb992c9
					
				
							
								
								
									
										4
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.prettierrc
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user