Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Web UI page #87

Merged
merged 1 commit into from
Apr 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,12 @@ indent_size = 2
[*.sh]
end_of_line = lf
[*.{cmd, bat}]
end_of_line = crlf
end_of_line = crlf

# JavaScript files
[*.{js,json}]
indent_size= 2

# Html files
[*.html]
indent_size= 2
4 changes: 4 additions & 0 deletions KeyVault.Acmebot/KeyVault.Acmebot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.2" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.5" />
<PackageReference Include="WebJobs.Extensions.HttpApi" Version="1.0.2" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
Expand Down
26 changes: 26 additions & 0 deletions KeyVault.Acmebot/StaticPageFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Azure.WebJobs.Extensions.HttpApi;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace KeyVault.Acmebot
{
public class StaticPageFunctions : HttpFunctionBase
{
public StaticPageFunctions(IHttpContextAccessor httpContextAccessor)
: base(httpContextAccessor)
{
}

[FunctionName(nameof(StaticPage))]
public IActionResult StaticPage(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "static-page/index")] HttpRequest req,
ILogger log)
{
return File("index.html", "text/html");
}
}
}
177 changes: 177 additions & 0 deletions KeyVault.Acmebot/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Key Vault Acmebot</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.1/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>
<body>
<section class="section">
<div class="container">
<h1 class="title">
Add Certificate
</h1>
<div id="app">
<div class="field is-horizontal">
<div class="field-label">
<label class="label">DNS Zone</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<div class="select" v-bind:class="{ 'is-loading': loading }">
<select v-model="zoneName" v-on:change="reset">
<option disabled value="">Please select one</option>
<option v-for="zone in zones" :value="zone">{{ zone }}</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label">
<label class="label">Domains</label>
</div>
<div class="field-body">
<div class="field has-addons">
<p class="control">
<input v-model="recordName" class="input" type="text" placeholder="Record name">
</p>
<p class="control">
<a class="button is-static">
.{{ zoneName }}
</a>
</p>
<p class="control">
<button class="button is-info" v-on:click="add">Add</button>
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label"></div>
<div class="field-body">
<div class="content">
<div class="tags">
<span v-for="domain in domains" class="tag is-light is-medium">
{{ domain }}
<button class="delete is-small" v-on:click="remove(domain)"></button>
</span>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label"></div>
<div class="field-body">
<div class="field">
<div class="control">
<button class="button is-primary" v-on:click="submit" v-bind:class="{ 'is-loading': sending }">Submit</button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
const delay = (millisecondsDelay) => {
return new Promise(resolve => setTimeout(() => resolve(), millisecondsDelay));
}

const app = new Vue({
el: "#app",
data: {
zones: [],
zoneName: "",
domains: [],
recordName: "",
loading: false,
sending: false
},
methods: {
load: async function () {
this.loading = true;

try {
const response = await axios.get("/api/get-dns-zones");

if (response.status === 200) {
this.$set(this, "zones", response.data);
}
} catch (error) {
alert(error);
}

this.loading = false;
},
reload: function () {
this.zones = [];
this.zoneName = "";
this.domains = [];
this.recordName = "";

this.load();
},
add: function () {
if (this.zoneName === "") {
return;
}

const domain = this.recordName === "" ? this.zoneName : this.recordName + "." + this.zoneName;

if (this.domains.indexOf(domain) === -1) {
this.domains.push(domain);
}

this.recordName = "";
},
remove: function (domain) {
this.domains = this.domains.filter(x => x !== domain);
},
reset: function () {
this.domains = [];
this.recordName = "";
},
submit: async function () {
if (this.domains.length === 0) {
alert("At least one domain is required");
return;
}

this.sending = true;

var response = await axios.post("/api/add-certificate", { Domains: this.domains });

while (true) {
await delay(5000);

try {
response = await axios.get(response.headers["location"]);
} catch {
alert("An error has occurred. No certificate was issued.");
break;
}

if (response.status === 200) {
alert("The certificate was successfully issued.");
break;
}
}

this.reload();
this.sending = false;
}
},
beforeMount: function () {
this.load();
}
});
</script>
</body>
</html>
4 changes: 2 additions & 2 deletions KeyVault.Acmebot/proxies.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"matchCondition": {
"route": "add-certificate"
},
"backendUri": "https://shibayan.blob.core.windows.net/azure-keyvault-letsencrypt/index.v2.html"
"backendUri": "http://localhost/api/static-page/index"
}
}
}
}