pull/125/head
Bálint Szekeres 2019-11-11 00:20:17 +01:00
parent 0f8d62a9ab
commit 4b60c9e481
17 changed files with 332 additions and 162 deletions

View File

Before

Width:  |  Height:  |  Size: 310 B

After

Width:  |  Height:  |  Size: 310 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

@ -0,0 +1,98 @@
<span class="step" ng-if="steps[step].slug === 'download'"><!--
step: download
--><ol>
<li>
<strong>Download</strong> generated config: <strong><a href="#" ng-click="downloadZip()">nginxconfig.io-{{ getDomains().join(',') }}.zip</a></strong>
</li>
<li>
<strong>Upload</strong> to server's <code>{{ data.directory_nginx.replace(endingSlashRegex, '') }}</code> directory<br>
or <strong>Copy</strong> as Base64 string: <strong><a href="#" ng-mouseenter="prepareBase64()" ng-click="copyAsBase64()" ngclipboard data-clipboard-target="#base64-zip-line" ngclipboard-success="clipboardSuccess('base64-zip-line')">Copy to clipboard</a></strong> and <strong>Paste</strong> from clipboard and run the command<br>
(<code>echo 'BASE64' | base64 --decode > {{ data.directory_nginx }}nginxconfig.io-{{ getDomains().join(',') }}.zip</code>)
</li>
<li>
Go to NGINX directory (over SSH):<br>
<code><span class="hljs-section">cd</span> {{ data.directory_nginx.replace(endingSlashRegex, '') }}</code>
</li>
<li>
<strong>Backup</strong> current configuration:<br>
<code><span class="hljs-section">tar</span> <span class="hljs-attribute">-czvf</span> nginx_$(date +'%F_%H-%M-%S').tar.gz nginx.conf sites-available/ sites-enabled/ nginxconfig.io/</code>
</li>
<li>
<strong>Unzip</strong> the uploaded archive:<br>
<code><span class="hljs-section">unzip</span> <span class="hljs-attribute">-o</span> nginxconfig.io-{{ getDomains().join(',') }}.zip</code><br>
(you probably need to install <strong>unzip</strong>: <code><span class="hljs-section"></span><strong>sudo</strong> <span class="hljs-section">apt-get</span> <span class="hljs-attribute">install</span> unzip</code>)
</li>
</ol></span><!--
--><span class="step" ng-if="steps[step].slug === 'ssl'"><ol><!--
step: ssl
--><!--
✔ SSL DH required --><li ng-if="isSSLDHRequired()">Generate <strong>Diffie-Hellman keys</strong>:<br>
<code><span class="hljs-section">openssl</span> <span class="hljs-attribute">dhparam</span> <span class="hljs-attribute">-out</span> {{ data.directory_nginx }}dhparam.pem <span class="hljs-number">{{ sslProfiles[ data.ssl_profile ].dh_param_size }}</span></code>
</li><!--
✔ Let's Encrypt
--><li ng-if="hasCertLetsEncrypt()">Create a common <strong>ACME-challenge</strong> directory (for <strong>Let's Encrypt</strong>):<br>
<code><span class="hljs-section">mkdir</span> <span class="hljs-attribute">-p</span> {{ data.directory_letsencrypt.replace(endingSlashRegex, '') }}</code><br>
<code><span class="hljs-section">chown</span> <span class="hljs-attribute">{{ data.user }}</span> {{ data.directory_letsencrypt.replace(endingSlashRegex, '') }}</code></li></ol></span><!--
--><span class="step" ng-if="steps[step].slug === 'certbot'"><!--
step: certbot
--><ol>
<li>
Comment out SSL related directives in configuration:<br>
<code><span class="hljs-section">sed</span> <span class="hljs-attribute">-i -r</span> 's/(listen .*443)/\1;#/g; s/(ssl_(certificate|certificate_key|trusted_certificate) )/#;#\1/g'<span ng-if="isUnified()"><!--
--> {{ data.directory_nginx }}nginx.conf</span><span ng-if="isModularized()"><span ng-repeat="(_site, _domain) in getDomains() track by $index" ng-if="isCertLetsEncrypt(_site)"><!--
--> {{ data.directory_nginx }}sites-{{ isSymlink() ? 'available' : 'enabled' }}/{{ _domain }}.conf</span></span></code>
</li>
<li>
Reload NGINX:<br>
<code><strong>sudo</strong> <span class="hljs-section">nginx</span> <span class="hljs-attribute">-t</span> && <strong>sudo</strong> <span class="hljs-section">systemctl</span> <span class="hljs-attribute">reload</span> nginx</code>
</li>
<li>
Obtain certificate{{ getDomains().length > 1 ? 's' : '' }}:<br>
<div ng-repeat="(_site, _domain) in getDomains() track by $index" ng-if="isCertLetsEncrypt(_site)"><code>
<span class="hljs-section">certbot</span> <!--
--><span class="hljs-attribute">certonly</span> <!--
--><span class="hljs-attribute">--webroot</span> <!--
--><span ng-if="isNonWWW(_site) || isRedirect(_site)"><span class="hljs-attribute" tooltips tooltip-template="--domain" tooltip-side="top">-d</span> {{ _domain.indexOf('-') !== -1 ? '"' + _domain + '"' : _domain }} </span><!--
--><span ng-if="isWWW(_site) || isRedirect(_site)"><span class="hljs-attribute" tooltips tooltip-template="--domain" tooltip-side="top">-d</span> {{ _domain.indexOf('-') !== -1 ? '"' : '' }}www.{{ _domain }}{{ _domain.indexOf('-') !== -1 ? '"' : '' }} </span><!--
--><span ng-if="isCDN(_site)"><span class="hljs-attribute" tooltips tooltip-template="--domain" tooltip-side="top">-d</span> {{ _domain.indexOf('-') !== -1 ? '"' : '' }}cdn.{{ _domain }}{{ _domain.indexOf('-') !== -1 ? '"' : '' }} </span><!--
--><span class="hljs-attribute">--email</span> {{ data.sites[_site].email ? data.sites[_site].email : 'info@' + _domain }} <!--
--><span class="hljs-attribute" tooltips tooltip-template="--webroot-path" tooltip-side="top">-w</span> {{ data.directory_letsencrypt.replace(endingSlashRegex, '') }} <!--
--><span class="hljs-attribute" tooltips tooltip-template="--non-interactive" tooltip-side="top">-n</span> <!--
--><span class="hljs-attribute">--agree-tos</span> <!--
--><span class="hljs-attribute">--force-renewal</span></code></div>
</li>
<li>
Reload NGINX:<br>
<code><strong>sudo</strong> <span class="hljs-section">nginx</span> <span class="hljs-attribute">-t</span> && <strong>sudo</strong> <span class="hljs-section">systemctl</span> <span class="hljs-attribute">reload</span> nginx</code>
</li>
<li>
Configure Certbot to reload NGINX after success renew:<br>
<code><span class="hljs-section">echo</span> <span class="hljs-attribute">-e</span> '#!/bin/bash\nnginx -t && systemctl reload nginx' | <strong>sudo</strong> <span class="hljs-section">tee</span> /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh</code><br>
<code><strong>sudo</strong> <span class="hljs-section">chmod</span> <span class="hljs-attribute">a+x</span> /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh</code>
</li>
</ol></span><!--
--><span class="step" ng-if="steps[step].slug === 'live'"><ol><!--
step: live
--><li>
Reload NGINX:<br>
<code><strong>sudo</strong> <span class="hljs-section">nginx</span> <span class="hljs-attribute">-t</span> && <strong>sudo</strong> <span class="hljs-section">systemctl</span> <span class="hljs-attribute">reload</span> nginx</code>
</li></ol></span>

View File

@ -1,4 +1,4 @@
<span class="step" ng-if="activeStep === 'download'"><!--
<span class="step" ng-if="steps[step].slug === 'download'"><!--
step: download
@ -16,7 +16,7 @@
--><span class="step" ng-if="activeStep === 'ssl'"><!--
--><span class="step" ng-if="steps[step].slug === 'ssl'"><!--
step: ssl
@ -33,7 +33,7 @@
--><span class="step" ng-if="activeStep === 'certbot'"><!--
--><span class="step" ng-if="steps[step].slug === 'certbot'"><!--
step: certbot
@ -69,7 +69,7 @@
--><span class="step" ng-if="activeStep === 'live'"><!--
--><span class="step" ng-if="steps[step].slug === 'live'"><!--
step: live

View File

@ -9,7 +9,7 @@
<div class="tab-content common-content">
<ul ng-if="layout === 'do'" class="nav nav-pills nav-fill" role="tablist">
<li ng-repeat="(key, tab) in tabs_common" class="nav-item">
<a class="nav-link" ng-mouseenter="setTabCommon(key)" ng-class="{ 'active': tab_common === key, 'changed': commonChanges[tab.slug], 'visited': key < tab_common }">{{ tab.name }}<small ng-cloak>({{ commonChanges[tab.slug] }})</small></a>
<a class="nav-link" ng-click="setTabCommon(key)" ng-class="{ 'active': tab_common === key, 'changed': commonChanges[tab.slug], 'visited': key < tab_common }">{{ tab.name }}<small ng-cloak>({{ commonChanges[tab.slug] }})</small></a>
</li>
</ul>
<div class="tab-pane tab-https" ng-class="{ 'active': tabs_common[tab_common].slug === 'https' }">
@ -399,7 +399,7 @@
</div>
</div>
<div class="tab-navigation-buttons" ng-if="layout === 'do'">
<button class="btn btn-outline-secondary" ng-click="setTabCommonBack()">Back</button>
<button class="btn btn-primary" ng-click="setTabCommonNext()">Next</button>
<button class="btn btn-outline-secondary" ng-click="setTabCommonBack()" ng-class="{ disabled: tab_common === 0 }">Back</button>
<button class="btn btn-primary" ng-click="setTabCommonNext()" ng-class="{ disabled: tab_common === tabs_common.length - 1 }">Next</button>
</div>
</div>

View File

@ -7,7 +7,7 @@
<div class="tab-content site-content">
<ul ng-if="layout === 'do'" class="nav nav-pills nav-fill" role="tablist">
<li ng-repeat="(key, tab) in tabs_site" class="nav-item">
<a class="nav-link" ng-mouseenter="setTabSite(key)" ng-class="{ 'active': tab_site === key, 'changed': getSiteTabChanges(tab.slug), 'visited': key < tab_site }">{{ tab.name }}<small ng-cloak>({{ getSiteTabChanges('php') }})</small></a>
<a class="nav-link" ng-click="setTabSite(key)" ng-class="{ 'active': tab_site === key, 'changed': getSiteTabChanges(tab.slug), 'visited': key < tab_site }">{{ tab.name }}<small ng-cloak>({{ getSiteTabChanges('php') }})</small></a>
</li>
</ul>
<div class="tab-pane tab-presets" ng-class="{ 'active': tabs_site[tab_site].slug === 'presets' }">
@ -426,7 +426,7 @@
</div>
</div>
<div class="tab-navigation-buttons" ng-if="layout === 'do'">
<button class="btn btn-outline-secondary" ng-click="setTabSiteBack()">Back</button>
<button class="btn btn-primary" ng-click="setTabSiteNext()">Next</button>
<button class="btn btn-outline-secondary" ng-click="setTabSiteBack()" ng-class="{ disabled: tab_site === 0 }">Back</button>
<button class="btn btn-primary" ng-click="setTabSiteNext()" ng-class="{ disabled: tab_site === tabs_site.length - 1 }">Next</button>
</div>
</div>

View File

@ -66,7 +66,11 @@
</section>
<section class="steps">
<div class="container">
<div class="row">
<div ng-if="layout === 'do'">
<h5>Setup and Files</h5>
<div class="card" ng-include="'partials/steps-do.html'"></div>
</div>
<div ng-if="layout === 'default'" class="row">
<div class="col-xl-10 offset-xl-1">
<div ng-include="'partials/steps.html'"></div>
</div>
@ -75,16 +79,17 @@
</section>
<main ng-class="{ 'active': masonryInit }">
<div class="container">
<div class="col-xl-10 offset-xl-1">
<div class="commands" ng-cloak>
<pre><code class="hljs bash" ng-include="'templates/commands.html?v=COMMIT_HASH'"></code></pre>
</div>
</div>
<div class="row grid">
<div class="grid-sizer col-xl-6"></div>
<div class="grid-item col-xl-12 mb-3 text-center" ng-cloak>
<button class="btn btn-primary btn-sm btn-download" ng-click="downloadZip()"><img src="assets/img/download.svg" alt="Download"> Generated config <small>(.zip)</small></button>
<button class="btn btn-success btn-sm btn-download btn-base64" ng-mouseenter="prepareBase64()" ng-click="copyAsBase64()" ngclipboard data-clipboard-target="#base64-zip-line" ngclipboard-success="clipboardSuccess('base64-zip-line')"><img src="assets/img/download.svg" alt="Download"> Copy Base64 <small>(inline)</small></button>
<div class="grid-item col-xl-12 mb-3" ng-cloak>
<div ng-if="layout === 'default'" class="text-center">
<button class="btn btn-primary btn-sm btn-download" ng-click="downloadZip()"><img src="assets/img/download.svg" alt="Download"> Generated config <small>(.zip)</small></button>
<button class="btn btn-success btn-sm btn-download btn-base64" ng-mouseenter="prepareBase64()" ng-click="copyAsBase64()" ngclipboard data-clipboard-target="#base64-zip-line" ngclipboard-success="clipboardSuccess('base64-zip-line')"><img src="assets/img/download.svg" alt="Download"> Copy Base64 <small>(inline)</small></button>
</div>
<div ng-if="layout === 'do'" class="text-center buttons">
<button class="btn btn-success btn-download" ng-click="downloadZip()">Download Config</button>
<button class="btn btn-primary btn-download btn-base64" ng-mouseenter="prepareBase64()" ng-click="copyAsBase64()" ngclipboard data-clipboard-target="#base64-zip-line" ngclipboard-success="clipboardSuccess('base64-zip-line')">Copy Base64</button>
</div>
</div>
<div class="base64-zip-line-container">
<div id="base64-zip-line">{{ base64 }}</div>

View File

@ -0,0 +1,12 @@
<ul class="nav nav-pills nav-fill" role="tablist">
<li class="nav-item" ng-repeat="(key, _step) in steps" ng-class="[_step.slug, !_step.active() ? 'disabled' : '']">
<a class="nav-link" ng-class="{ active: key === step, visited: key < step }" ng-click="setActiveStep(key)">{{ _step.name }}</a>
</li>
</ul>
<div class="commands-do" ng-include="'partials/commands-do.html?v=COMMIT_HASH'" ng-cloak></div>
<div class="tab-navigation-buttons" ng-if="layout === 'do'">
<button class="btn btn-outline-secondary" ng-click="setStepBack()" ng-class="{ disabled: step === 0 }">Back</button>
<button class="btn btn-primary" ng-click="setStepNext()" ng-class="{ disabled: step === steps.length - 1 }">Next</button>
</div>

View File

@ -1,30 +1,14 @@
<ol ng-attr-data-active-step="{{ activeStep }}">
<ol class="step-icons" ng-attr-data-active-step="{{ steps[step].slug }}">
<li
class="download"
ng-mouseenter="setActiveStep('download')">
<div class="circle" ng-include="'/assets/img/download-cloud.svg'"></div>
<span class="counter"></span>Download
</li>
<li
class="ssl"
ng-if="isHTTPS() && (isSSLDHRequired() || isCertLetsEncrypt())"
ng-mouseenter="setActiveStep('ssl')">
<div class="circle" ng-include="'/assets/img/lock.svg'"></div>
<span class="counter"></span>SSL init
</li>
<li
class="certbot"
ng-if="isHTTPS() && isCertLetsEncrypt()"
ng-mouseenter="setActiveStep('certbot')">
<div class="circle" ng-include="'/assets/img/terminal.svg'"></div>
<span class="counter"></span>Certbot
</li>
<li
class="live"
ng-mouseenter="setActiveStep('live')">
<div class="circle" ng-include="'/assets/img/check-circle.svg'"></div>
<span class="counter"></span>Go Live!
ng-repeat="(key, step) in steps"
ng-if="step.active()"
ng-class="[step.slug]"
ng-mouseenter="setActiveStep(key)">
<div class="circle" ng-include="'/assets/img/steps/' + step.slug + '.svg'"></div>
<span class="counter"></span>{{ step.name }}
</li>
</ol>
<div class="commands" ng-cloak>
<pre><code class="hljs bash" ng-include="'partials/commands.html?v=COMMIT_HASH'"></code></pre>
</div>

View File

@ -370,6 +370,7 @@
$scope.site = 0;
$scope.tab_site = 0;
$scope.tab_common = 0;
$scope.step = 0;
$scope.tabs_site = [
{
@ -445,26 +446,36 @@
{
name: 'Download',
slug: 'download',
active: function() {
return true;
},
},
{
name: 'SSL init',
slug: 'ssl',
active: function() {
return $scope.isHTTPS() && ($scope.isSSLDHRequired() || $scope.isCertLetsEncrypt());
},
},
{
name: 'Cerbot',
slug: 'certbot',
active: function() {
return $scope.isHTTPS() && $scope.isCertLetsEncrypt();
},
},
{
name: 'Go Live!',
slug: 'live',
active: function() {
return true;
},
},
];
$scope.siteChanges = {};
$scope.commonChanges = {};
$scope.activeStep = 'download';
$scope.base64 = '';
$scope.gzipTypes = 'text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml';
@ -711,9 +722,21 @@
};
$scope.setActiveStep = function(step) {
$scope.activeStep = step;
$scope.step = step;
};
$scope.setStepBack = function() {
if ($scope.step > 0) {
$scope.step--;
}
};
$scope.setStepNext = function() {
if ($scope.step < $scope.steps.length - 1) {
$scope.step++;
}
}
$scope.getSiteChanges = function(site) {
if ($scope.siteChanges[site] === undefined) {
return undefined;

View File

@ -0,0 +1,22 @@
main .file .code,
section.steps .commands {
overflow-x: auto;
font-size: 0.75rem;
line-height: 1.25;
background-color: #f8f8f8;
border: 1px solid #e8e8e8;
pre {
margin-bottom: 0;
font-size: inherit;
code {
display: block;
padding: 8px 8px 12px;
-moz-tab-size: 4;
tab-size: 4;
overflow: visible;
overflow-x: visible;
}
}
}

View File

@ -257,29 +257,6 @@ main {
}
}
.commands {
margin-bottom: 1rem;
line-height: 1.35;
.step {
counter-reset: step-command-counter;
.counter {
display: inline-block;
margin-top: 0.15rem;
&::before {
counter-increment: step-command-counter;
content: counter(step-command-counter);
}
}
& > span:first-of-type .counter {
margin-top: 0;
}
}
}
.file {
margin-bottom: 2rem;
@ -301,27 +278,4 @@ main {
left: -9999px;
}
}
.commands,
.file .code {
overflow-x: auto;
font-size: 0.75rem;
line-height: 1.25;
background-color: #f8f8f8;
border: 1px solid #e8e8e8;
pre {
margin-bottom: 0;
font-size: inherit;
code {
display: block;
padding: 8px 8px 12px;
-moz-tab-size: 4;
tab-size: 4;
overflow: visible;
overflow-x: visible;
}
}
}
}

View File

@ -1,5 +1,5 @@
section.steps {
ol {
ol.step-icons {
display: flex;
flex-direction: row;
list-style: none;
@ -165,4 +165,27 @@ section.steps {
}
}
}
.commands {
margin-bottom: 1rem;
line-height: 1.35;
.step {
counter-reset: step-command-counter;
.counter {
display: inline-block;
margin-top: 0.15rem;
&::before {
counter-increment: step-command-counter;
content: counter(step-command-counter);
}
}
& > span:first-of-type .counter {
margin-top: 0;
}
}
}
}

View File

@ -11,6 +11,7 @@
@import 'header';
@import 'steps';
@import 'main';
@import 'codes';
@import 'sidebar';
@import 'footer';

View File

@ -56,6 +56,62 @@
background-color: #e5e5e5;
}
.nav-pills {
margin: 25px 0;
background-color: #ffffff;
border: 1px solid #dde1e8;
border-radius: 5px;
overflow: hidden;
.nav-item {
&:first-child {
.nav-link {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
}
&:last-child {
.nav-link {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-right: 0;
}
}
&.disabled {
pointer-events: none;
user-select: none;
opacity: 0.4;
}
.nav-link {
cursor: pointer;
position: relative;
border-right: 1px solid #dde1e8;
border-radius: 0;
&.active {
background-color: #0069ff;
&:hover {
color: #ffffff;
}
}
&.visited {
background-color: #dfeeff;
}
}
}
}
.tab-navigation-buttons {
margin: 20px 0 32px;
text-align: right;
}
header {
padding: 0;
background-color: #031b4e;
@ -220,73 +276,30 @@
}
}
.nav-pills {
margin: 25px 0;
background-color: #ffffff;
border: 1px solid #dde1e8;
border-radius: 5px;
overflow: hidden;
.nav-pills .nav-item .nav-link {
&.changed {
font-weight: 700;
.nav-item {
&:first-child {
.nav-link {
small {
display: inline;
color: #ccc;
top: 52.5%;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
@include media-breakpoint-up(xl) {
padding-left: 0.3rem;
}
}
}
&:last-child {
.nav-link {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-right: 0;
}
}
small {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: none;
color: #999;
.nav-link {
cursor: pointer;
position: relative;
border-right: 1px solid #dde1e8;
border-radius: 0;
&.active {
background-color: #0069ff;
&:hover {
color: #ffffff;
}
}
&.changed {
font-weight: 700;
small {
display: inline;
color: #ccc;
top: 52.5%;
@include media-breakpoint-up(xl) {
padding-left: 0.3rem;
}
}
}
&.visited {
background-color: #dfeeff;
}
small {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: none;
color: #999;
@include media-breakpoint-down(lg) {
right: 0.25rem;
}
}
@include media-breakpoint-down(lg) {
right: 0.25rem;
}
}
}
@ -324,11 +337,6 @@
}
}
.tab-navigation-buttons {
margin: 20px 0 32px;
text-align: right;
}
.btn-outline-light {
box-shadow: none !important;
color: #666;
@ -354,4 +362,44 @@
}
}
}
section.steps {
margin-top: 53px;
margin-bottom: 37px;
.card {
border: 1px solid #dee2e6;
background-color: #fafafa;
padding: 0.5rem 40px 0.25rem;
}
.commands-do {
ol {
li + li{
margin-top: 1rem;
}
}
code {
background-color: #e5e8ed;
color: #3b4e76;
border: 1px solid #cbcdd3;
border-radius: 3px;
font-style: italic;
padding-left: 3px;
padding-right: 3px;
}
}
}
main .buttons {
margin-bottom: 30px;
.btn {
margin: 0 10px;
font-weight: 700;
font-size: 1rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
}
}