ACME证书增加ZeroSSL支持

This commit is contained in:
刘祥超
2021-10-03 13:09:49 +08:00
parent 0bc8bdd841
commit 1fb491d2e1
28 changed files with 795 additions and 33 deletions

View File

@@ -2,4 +2,5 @@
<menu-item href="/servers/certs/acme" code="task">所有任务</menu-item>
<menu-item href="/servers/certs/acme/create" code="create">新申请</menu-item>
<menu-item href="/servers/certs/acme/users" code="user">ACME用户</menu-item>
<menu-item href="/servers/certs/acme/accounts" code="account">服务商账号</menu-item>
</first-menu>

View File

@@ -0,0 +1,41 @@
{$layout "layout_popup"}
<h3>添加账号</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<csrf-token></csrf-token>
<table class="ui table definition selectable">
<tr>
<td>账号名称 *</td>
<td>
<input type="text" name="name" maxlength="50" ref="focus" tabindex="1"/>
</td>
</tr>
<tr>
<td class="title">服务商 *</td>
<td>
<select class="ui dropdown auto-width" name="providerCode" v-model="providerCode" @change="changeProvider" tabindex="2">
<option value="">[选择服务商]</option>
<option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
</select>
<p class="comment" v-if="selectedProvider != null" v-html="selectedProvider.description"></p>
</td>
</tr>
<tbody v-show="selectedProvider != null && selectedProvider.requireEAB">
<tr>
<td>EAB Kid *</td>
<td>
<input type="text" name="eabKid" maxlength="100" tabindex="3"/>
<p class="comment" v-if="selectedProvider != null" v-html="selectedProvider.eabDescription"></p>
</td>
</tr>
<tr>
<td>EAB HMAC Key *</td>
<td>
<input type="text" name="eabKey" maxlength="300" tabindex="4"/>
</td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,16 @@
Tea.context(function () {
this.selectedProvider = null
this.changeProvider = function () {
if (this.providerCode.length == 0) {
this.selectedProvider = null
return
}
let that = this
this.selectedProvider = this.providers.$find(function (k, v) {
return v.code == that.providerCode
})
}
this.changeProvider()
})

View File

@@ -0,0 +1,46 @@
{$layout}
{$template "/left_menu_top"}
<div class="right-box without-tabbar">
{$template "../menu"}
<second-menu>
<menu-item @click.prevent="createAccount">[创建账号]</menu-item>
</second-menu>
<p class="comment" v-if="accounts.length == 0">暂时还没有服务商账号。</p>
<table class="ui table selectable celled" v-if="accounts.length > 0">
<thead>
<tr>
<th>名称</th>
<th>服务商</th>
<th class="four wide">EAB Kid</th>
<th class="four wide">EBA HMAC Key</th>
<th class="two wide">操作</th>
</tr>
</thead>
<tr v-for="account in accounts">
<td>
<a href="" @click.prevent="updateAccount(account.id)">{{account.name}} <i class="icon clone outline small"></i></a>
</td>
<td>
<span v-if="account.provider != null">{{account.provider.name}}</span>
</td>
<td>
<span v-if="account.eabKid.length > 0">{{account.eabKid}}</span>
<span v-else class="disabled">-</span>
</td>
<td>
<span v-if="account.eabKey.length > 0">{{account.eabKey}}</span>
<span v-else class="disabled">-</span>
</td>
<td>
<a href="" @click.prevent="updateAccount(account.id)">修改</a> &nbsp;
<a href="" @click.prevent="deleteAccount(account.id)">删除</a>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>
</div>

View File

@@ -0,0 +1,33 @@
Tea.context(function () {
this.createAccount = function () {
teaweb.popup(".createPopup", {
height: "24em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.updateAccount = function (accountId) {
teaweb.popup(".updatePopup?accountId=" + accountId, {
height: "24em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.deleteAccount = function (accountId) {
teaweb.confirm("确定要删除此账号吗?", function () {
this.$post(".delete")
.params({
accountId: accountId
})
.refresh()
})
}
})

View File

@@ -0,0 +1,41 @@
{$layout "layout_popup"}
<h3>修改账号</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<csrf-token></csrf-token>
<input type="hidden" name="accountId" :value="account.id"/>
<input type="hidden" name="providerCode" :value="account.providerCode"/>
<table class="ui table definition selectable">
<tr>
<td>账号名称 *</td>
<td>
<input type="text" name="name" maxlength="50" ref="focus" v-model="account.name" tabindex="1"/>
</td>
</tr>
<tr>
<td class="title">服务商 *</td>
<td>
<span v-if="account.provider != null">{{account.provider.name}}</span>
<span v-else class="disabled">服务商已失效</span>
<p class="comment" v-if="account.provider != null" v-html="account.provider.description"></p>
</td>
</tr>
<tbody v-show="account.provider != null && account.provider.requireEAB">
<tr>
<td>EAB Kid *</td>
<td>
<input type="text" name="eabKid" maxlength="100" v-model="account.eabKid" tabindex="3"/>
<p class="comment" v-if="account.provider != null" v-html="account.provider.eabDescription"></p>
</td>
</tr>
<tr>
<td>EAB HMAC Key *</td>
<td>
<input type="text" name="eabKey" maxlength="300" v-model="account.eabKey" tabindex="4"/>
</td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,3 @@
Tea.context(function () {
})

View File

@@ -64,15 +64,24 @@
<!-- 选择用户 -->
<div v-show="step == 'user'">
<table class="ui table definition selectable">
<tr>
<td class="title">选择用户</td>
<tr>
<td class="title">选择服务商 *</td>
<td>
<select class="ui dropdown auto-width" v-model="providerCode" @change="changeProvider">
<option value="">[选择服务商]</option>
<option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
</select>
</td>
</tr>
<tr v-if="providerCode.length > 0">
<td class="title">选择用户 *</td>
<td>
<div v-if="users.length > 0">
<div class="ui fields inline">
<div class="ui field">
<select class="ui dropdown" v-model="userId">
<option value="0">[请选择]</option>
<option v-for="user in users" :value="user.id">{{user.email}}{{user.description}}</option>
<option v-for="user in users" :value="user.id" v-if="user.providerCode == providerCode">{{user.email}}{{user.description}}</option>
</select>
</div>
<div class="ui field">
@@ -98,10 +107,10 @@
<tr v-show="authType == 'dns'">
<td class="title">选择DNS服务商 *</td>
<td>
<div v-if="providers.length > 0">
<div v-if="dnsProviders.length > 0">
<select class="ui dropdown auto-width" v-model="dnsProviderId">
<option value="0">[请选择]</option>
<option v-for="provider in providers" :value="provider.id">{{provider.name}}{{provider.typeName}}</option>
<option v-for="provider in dnsProviders" :value="provider.id">{{provider.name}}{{provider.typeName}}</option>
</select>
</div>
<p class="comment">用于自动创建域名解析记录。</p>

View File

@@ -28,6 +28,8 @@ Tea.context(function () {
this.createUser = function () {
let that = this
teaweb.popup("/servers/certs/acme/users/createPopup", {
height: "27em",
width: "44em",
callback: function (resp) {
teaweb.successToast("创建成功")
@@ -40,13 +42,23 @@ Tea.context(function () {
that.users.unshift({
id: acmeUser.id,
description: description,
email: acmeUser.email
email: acmeUser.email,
providerCode: acmeUser.providerCode
})
}
})
}
this.providerCode = ""
this.changeProvider = function () {
this.userId = 0
}
this.doUser = function () {
if (this.providerCode.length == 0) {
teaweb.warn("请选择一个证书服务商")
return
}
if (this.userId == 0) {
teaweb.warn("请选择一个申请证书的用户")
return

View File

@@ -42,10 +42,12 @@
</thead>
<tr v-for="(task, index) in tasks" :class="{warning: runningIndex == index}">
<td>{{task.acmeUser.email}}
<div style="margin-top: 1em">
<tiny-basic-label class="olive" v-if="task.authType == 'dns'">DNS</tiny-basic-label>
<tiny-basic-label class="olive" v-if="task.authType == 'http'">HTTP</tiny-basic-label>
</div>
<div>
<grey-label class="olive" v-if="task.authType == 'dns'">DNS</grey-label>
<grey-label class="olive" v-if="task.authType == 'http'">HTTP</grey-label>
<grey-label v-if="task.acmeUser.provider != null">{{task.acmeUser.provider.name}}</grey-label>
<grey-label v-if="task.acmeUser.account != null">{{task.acmeUser.account.name}}</grey-label>
</div>
</td>
<td nowrap="">
<div v-for="domain in task.domains">

View File

@@ -11,6 +11,31 @@
<p class="comment">用于自动注册用户的邮箱。</p>
</td>
</tr>
<tr>
<td>所属服务商 *</td>
<td>
<select class="ui dropdown auto-width" name="providerCode" v-model="providerCode" @change="changeProvider">
<option value="">[选择服务商]</option>
<option v-for="provider in providers" :value="provider.code">{{provider.name}}</option>
</select>
</td>
</tr>
<tr v-if="selectedProvider != null">
<td>所属服务商账号 <span v-if="selectedProvider.requireEAB">*</span><em v-else>(可选)</em></td>
<td>
<div class="ui fields inline">
<div class="ui field" v-if="accounts.length > 0">
<select class="ui dropdown auto-width" name="accountId" v-model="accountId">
<option value="0">[选择账号]</option>
<option v-for="account in accounts" :value="account.id">{{account.name}}</option>
</select>
</div>
<div class="ui field">
<a href="" @click.prevent="addAccount">[添加]</a>
</div>
</div>
</td>
</tr>
<tr>
<td>备注</td>
<td>

View File

@@ -0,0 +1,54 @@
Tea.context(function () {
this.providerCode = ""
this.selectedProvider = null
this.accounts = []
this.accountId = 0
this.changeProvider = function () {
this.accountId = 0
if (this.providerCode.length == 0) {
return
}
let that = this
let provider = this.providers.$find(function (k, v) {
return v.code == that.providerCode
})
if (provider == null) {
return
}
this.selectedProvider = provider
this.$post(".accountsWithCode")
.params({
code: provider.code
})
.success(function (resp) {
this.accounts = resp.data.accounts
})
}
this.addAccount = function () {
let that = this
teaweb.popup("/servers/certs/acme/accounts/createPopup?providerCode=" + this.providerCode, {
height: "24em",
callback: function () {
teaweb.successToast("创建成功,已自动选中", 1500, function () {
that.$post(".accountsWithCode")
.params({
code: that.providerCode
})
.success(function (resp) {
that.accounts = resp.data.accounts
if (that.accounts.length > 0) {
that.accountId = that.accounts[0].id
}
})
})
}
})
}
})

View File

@@ -14,13 +14,19 @@
<table class="ui table selectable" v-if="users.length > 0">
<thead>
<tr>
<th>Email</th>
<th>用户Email</th>
<th>备注</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="user in users">
<td>{{user.email}}</td>
<td>
<a href="" @click.prevent="updateUser(user.id)">{{user.email}} <i class="icon clone outline small"></i></a>
<div>
<grey-label v-if="user.provider != null">{{user.provider.name}}</grey-label>
<grey-label v-if="user.account != null">{{user.account.name}}</grey-label>
</div>
</td>
<td>
<span v-if="user.description.length > 0">{{user.description}}</span>
<span v-else class="disabled">-</span>

View File

@@ -1,6 +1,8 @@
Tea.context(function () {
this.createUser = function () {
teaweb.popup(Tea.url(".createPopup"), {
height: "27em",
width: "44em",
callback: function () {
teaweb.success("创建成功", function () {
teaweb.reload()
@@ -11,6 +13,8 @@ Tea.context(function () {
this.updateUser = function (userId) {
teaweb.popup("/servers/certs/acme/users/updatePopup?userId=" + userId, {
height: "27em",
width: "44em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()

View File

@@ -12,6 +12,14 @@
<p class="comment">用于自动注册用户的邮箱,不允许修改。</p>
</td>
</tr>
<tr v-if="user.provider != null">
<td>所属服务商</td>
<td>{{user.provider.name}}</td>
</tr>
<tr v-if="user.account != null">
<td>所属服务商账号</td>
<td>{{user.account.name}}</td>
</tr>
<tr>
<td>备注</td>
<td>