1.4.5.2
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<first-menu>
|
||||
<menu-item :href="'/servers/server/settings/waf?serverId=' + serverId" code="index">设置</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/groups?serverId=' + serverId + '&type=inbound&firewallPolicyId='+firewallPolicyId" code="inbound" v-if="firewallPolicyId > 0">入站规则</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/groups?serverId=' + serverId + '&type=outbound&firewallPolicyId='+firewallPolicyId" code="outbound" v-if="firewallPolicyId > 0">出站规则</menu-item>
|
||||
|
||||
<span class="ui item disabled">|</span>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/countries?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="country" v-if="firewallPolicyId > 0">国家/地区封禁</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/provinces?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="province" v-if="firewallPolicyId > 0">省份封禁</menu-item>
|
||||
<span class="ui item disabled">|</span>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/allowList?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="allowList" v-if="firewallPolicyId > 0">白名单</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/denyList?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="denyList" v-if="firewallPolicyId > 0">黑名单</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/greyList?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="greyList" v-if="firewallPolicyId > 0">灰名单</menu-item>
|
||||
<menu-item :href="'/servers/server/settings/waf/ipadmin/test?serverId=' + serverId + '&firewallPolicyId='+firewallPolicyId" code="test">IP检查</menu-item>
|
||||
</first-menu>
|
||||
@@ -0,0 +1,74 @@
|
||||
{$layout}
|
||||
{$template "../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<h3>分组<a href="" @click.prevent="updateGroup(group.id)">[修改]</a></h3>
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">名称</td>
|
||||
<td>{{group.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>描述</td>
|
||||
<td>
|
||||
<span v-if="group.description.length == 0" class="disabled">暂时还没有描述。</span>
|
||||
<span v-if="group.description.length > 0">{{group.description}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>启用状态</td>
|
||||
<td>
|
||||
<label-on :v-is-on="group.isOn"></label-on>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3 style="padding-top:0.8em">规则集<a href="" @click.prevent="createSet(group.id)">[添加规则集]</a> </h3>
|
||||
<p class="comment" v-if="sets == null || sets.length == 0">暂时还没有规则。</p>
|
||||
<table class="ui table selectable celled" id="sortable-table" v-if="sets != null && sets.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:3em"></th>
|
||||
<th nowrap="">规则集名称</th>
|
||||
<th nowrap="">规则</th>
|
||||
<th nowrap="" class="center" style="width: 6em">规则关系<tip-icon content="规则关系指的是<strong>单个规则集</strong>中的各个规则之间的关系,如果是“和(AND)”表示所有规则都必须满足条件,如果是“或(OR)”表示任一规则满足条件即可。<br/><br/>多个规则集之间没有任何关系,满足任一个规则集即停止向下匹配。"></tip-icon></th>
|
||||
<th nowrap="">动作</th>
|
||||
<th class="three op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="set in sets" :data-set-id="set.id">
|
||||
<tr :class="{warning: highlightedSetId == set.id}">
|
||||
<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
|
||||
<td nowrap=""><a :name="'set' + set.id"></a><a href="" @click.prevent="updateSet(set.id)"><span :class="{disabled:!set.isOn}">{{set.name}}</span> <i class="icon expand small"></i> </a>
|
||||
<p style="margin-top:0.5em">
|
||||
<label-on :v-is-on="set.isOn"></label-on>
|
||||
</p>
|
||||
</td>
|
||||
<td class="rules-box">
|
||||
<div v-for="rule in set.rules" style="margin-top: 0.4em;margin-bottom:0.4em">
|
||||
<http-firewall-rule-label :v-rule="rule"></http-firewall-rule-label>
|
||||
</div>
|
||||
<span class="ui disabled" v-if="set.rules.length == 0">暂时还没有规则</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
<span v-if="set.rules != null && set.rules.length > 1">
|
||||
<span v-if="set.connector.toUpperCase() == 'OR'">或</span><span v-else>和</span>
|
||||
<span class="small grey">({{set.connector.toUpperCase()}})</span>
|
||||
</span>
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td nowrap="">
|
||||
<http-firewall-actions-view :v-actions="set.actions"></http-firewall-actions-view>
|
||||
</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="updateSet(set.id)">修改</a> <a href="" @click.prevent="updateSetOn(set.id, false)" v-if="set.isOn">停用</a><a href="" @click.prevent="updateSetOn(set.id, true)" v-if="!set.isOn"><span class="red">启用</span></a> <a href="" @click.prevent="deleteSet(set.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="comment" v-if="group.sets != null && group.sets.length > 1">所有规则匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>
|
||||
</div>
|
||||
103
EdgeUser/web/views/@default/servers/server/settings/waf/group.js
Normal file
103
EdgeUser/web/views/@default/servers/server/settings/waf/group.js
Normal file
@@ -0,0 +1,103 @@
|
||||
Tea.context(function () {
|
||||
this.highlightedSetId = 0
|
||||
|
||||
this.$delay(function () {
|
||||
let that = this
|
||||
sortTable(function () {
|
||||
let setIds = []
|
||||
document
|
||||
.querySelectorAll("tbody[data-set-id]")
|
||||
.forEach(function (v) {
|
||||
setIds.push(v.getAttribute("data-set-id"))
|
||||
})
|
||||
that.$post("/servers/components/waf/sortSets")
|
||||
.params({
|
||||
groupId: that.group.id,
|
||||
setIds: setIds
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.successToast("排序保存成功")
|
||||
})
|
||||
})
|
||||
|
||||
// 跳转到刚操作成功的记录集
|
||||
let opSetId = localStorage.getItem("goHTTPFirewallRuleSet")
|
||||
if (opSetId != null) {
|
||||
this.highlightedSetId = opSetId
|
||||
localStorage.removeItem("goHTTPFirewallRuleSet")
|
||||
document.querySelector("*[data-set-id='" + opSetId + "']").scrollIntoView({behavior: 'smooth'})
|
||||
}
|
||||
})
|
||||
|
||||
// 更改分组
|
||||
this.updateGroup = function (groupId) {
|
||||
teaweb.popup("/servers/components/waf/updateGroupPopup?groupId=" + groupId, {
|
||||
height: "20em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 创建规则集
|
||||
this.createSet = function (groupId) {
|
||||
let that = this
|
||||
teaweb.popup("/servers/components/waf/createSetPopup?firewallPolicyId=" + this.firewallPolicyId + "&groupId=" + groupId + "&type=" + this.type, {
|
||||
width: "50em",
|
||||
height: "40em",
|
||||
callback: function (resp) {
|
||||
teaweb.success("保存成功", function () {
|
||||
that.goSetId(resp.data.setId)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改规则集
|
||||
this.updateSet = function (setId) {
|
||||
let that = this
|
||||
teaweb.popup("/servers/components/waf/updateSetPopup?firewallPolicyId=" + this.firewallPolicyId + "&groupId=" + this.group.id + "&type=" + this.type + "&setId=" + setId, {
|
||||
width: "50em",
|
||||
height: "40em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
that.goSetId(setId)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 停用|启用规则集
|
||||
this.updateSetOn = function (setId, isOn) {
|
||||
let that = this
|
||||
this.$post("/servers/components/waf/updateSetOn")
|
||||
.params({
|
||||
setId: setId,
|
||||
isOn: isOn ? 1 : 0
|
||||
})
|
||||
.success(function () {
|
||||
that.goSetId(setId)
|
||||
})
|
||||
}
|
||||
|
||||
// 删除规则集
|
||||
this.deleteSet = function (setId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除此规则集吗?", function () {
|
||||
that.$post("/servers/components/waf/deleteSet")
|
||||
.params({
|
||||
groupId: this.group.id,
|
||||
setId: setId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转到刚操作的记录集ID
|
||||
this.goSetId = function (setId) {
|
||||
localStorage.setItem("goHTTPFirewallRuleSet", setId)
|
||||
teaweb.reload()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,52 @@
|
||||
{$layout}
|
||||
{$template "../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<second-menu>
|
||||
<a href="" class="item" @click.prevent="createGroup(type)">[添加分组]</a>
|
||||
</second-menu>
|
||||
|
||||
<p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p>
|
||||
|
||||
<table class="ui table selectable celled" v-if="groups.length > 0" id="sortable-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:3em"></th>
|
||||
<th>规则分组</th>
|
||||
<th class="center">规则集</th>
|
||||
<th class="three op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="group in groups" :data-group-id="group.id">
|
||||
<tr>
|
||||
<td style="text-align: center;"><i class="icon bars handle grey" title="拖动排序"></i> </td>
|
||||
<td><a :href="'/servers/server/settings/waf/group?serverId=' + serverId + '&firewallPolicyId=' + firewallPolicyId + '&type=' + type + '&groupId=' + group.id"><span :class="{disabled:!group.isOn}">{{group.name}}</span></a>
|
||||
<p class="comment" v-if="group.description.length > 0" style="padding-bottom:0">{{group.description}}</p>
|
||||
<p style="margin-top: 0.5em">
|
||||
<span v-if="group.isOn" class="ui label tiny basic green">启用</span>
|
||||
<span v-if="!group.isOn" class="ui label tiny basic red">停用</span>
|
||||
<span v-if="group.code.length > 0" class="ui label basic tiny">预置</span>
|
||||
<span v-if="group.code.length == 0" class="ui label basic tiny">自定义</span>
|
||||
</p>
|
||||
</td>
|
||||
<td class="center">
|
||||
<a :href="'/servers/server/settings/waf/group?serverId=' + serverId + '&firewallPolicyId=' + firewallPolicyId + '&type=' + type + '&groupId=' + group.id">{{group.countSets}}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a :href="'/servers/server/settings/waf/group?serverId=' + serverId + '&firewallPolicyId=' + firewallPolicyId + '&type=' + type + '&groupId=' + group.id">详情</a>
|
||||
<a href="" v-if="!group.isOn" @click.prevent="enableGroup(group.id)">启用</a><a href="" v-if="group.isOn" @click.prevent="disableGroup(group.id)">停用</a>
|
||||
<a href="" @click.prevent="deleteGroup(group.id)" v-if="group.canDelete">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="comment" v-if="groups.length > 0">所有规则匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,67 @@
|
||||
Tea.context(function () {
|
||||
// 排序
|
||||
this.$delay(function () {
|
||||
let that = this
|
||||
sortTable(function () {
|
||||
let groupIds = []
|
||||
document.querySelectorAll("tbody[data-group-id]")
|
||||
.forEach(function (v) {
|
||||
groupIds.push(v.getAttribute("data-group-id"))
|
||||
})
|
||||
|
||||
that.$post("/servers/components/waf/sortGroups")
|
||||
.params({
|
||||
firewallPolicyId: that.firewallPolicyId,
|
||||
type: that.type,
|
||||
groupIds: groupIds
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.successToast("排序保存成功")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// 启用
|
||||
this.enableGroup = function (groupId) {
|
||||
this.$post("/servers/components/waf/updateGroupOn")
|
||||
.params({
|
||||
groupId: groupId,
|
||||
isOn: 1
|
||||
})
|
||||
.refresh()
|
||||
|
||||
}
|
||||
|
||||
// 停用
|
||||
this.disableGroup = function (groupId) {
|
||||
this.$post("/servers/components/waf/updateGroupOn")
|
||||
.params({
|
||||
groupId: groupId,
|
||||
isOn: 0
|
||||
})
|
||||
.refresh()
|
||||
}
|
||||
|
||||
// 删除
|
||||
this.deleteGroup = function (groupId) {
|
||||
teaweb.confirm("确定要删除此规则分组吗?", function () {
|
||||
this.$post("/servers/components/waf/deleteGroup")
|
||||
.params({
|
||||
firewallPolicyId: this.firewallPolicyId,
|
||||
groupId: groupId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
// 添加分组
|
||||
this.createGroup = function (type) {
|
||||
teaweb.popup("/servers/components/waf/createGroupPopup?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type, {
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
{$layout}
|
||||
{$template "../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="webId" :value="webId"/>
|
||||
<http-firewall-config-box :v-firewall-config="firewallConfig" :v-firewall-policy="firewallPolicy"></http-firewall-config-box>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<second-menu>
|
||||
<menu-item @click.prevent="createIP('white')">添加IP</menu-item>
|
||||
<span class="item">|</span>
|
||||
<span class="item">ID: {{listId}} <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
|
||||
</second-menu>
|
||||
|
||||
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
|
||||
|
||||
<ip-list-table v-if="items.length > 0" :v-items="items" @update-item="updateItem" @delete-item="deleteItem"></ip-list-table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
Tea.context(function () {
|
||||
this.updateItem = function (itemId) {
|
||||
teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), {
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteItem = function (itemId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个IP吗?", function () {
|
||||
that.$post(".deleteIP")
|
||||
.params({
|
||||
"listId": this.listId,
|
||||
"itemId": itemId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加IP名单菜单
|
||||
*/
|
||||
this.createIP = function (type) {
|
||||
teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
|
||||
height: "28em",
|
||||
callback: function () {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,61 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/>
|
||||
<input type="hidden" name="exceptURLPatternsJSON" :value="JSON.stringify(exceptURLPatterns)"/>
|
||||
<input type="hidden" name="onlyURLPatternsJSON" :value="JSON.stringify(onlyURLPatterns)"/>
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">仅允许的区域</td>
|
||||
<td>
|
||||
<http-firewall-region-selector :v-countries="allowedCountries" :v-type="'allow'" @change="changeAllowedCountries"></http-firewall-region-selector>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">仅封禁的区域</td>
|
||||
<td>
|
||||
<p class="comment" v-if="allowedCountries.length > 0">由于你已设置"仅允许的区域",所以不需要再设置封禁区域。</p>
|
||||
<http-firewall-region-selector :v-countries="deniedCountries" :v-type="'deny'" v-show="allowedCountries.length == 0"></http-firewall-region-selector>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>例外URL <tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>限制URL <tip-icon content="只对这些URL做限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>提示内容</td>
|
||||
<td>
|
||||
<textarea v-model="countryHTML" name="countryHTML" rows="3"></textarea>
|
||||
<p class="comment">当客户端所在区域被封禁时提示页面的HTML内容;不填则表示使用默认的提示内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>允许搜索引擎</td>
|
||||
<td>
|
||||
<checkbox name="allowSearchEngine" v-model="allowSearchEngine"></checkbox>
|
||||
<p class="comment">选中后,表示如果请求来自常见搜索引擎的IP,则不受区域限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
Tea.context(function () {
|
||||
this.success = function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
|
||||
this.changeAllowedCountries = function (event) {
|
||||
this.allowedCountries = event.countries
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3 v-if="type == 'white'">添加IP到白名单</h3>
|
||||
<h3 v-if="type == 'black'">添加IP到黑名单</h3>
|
||||
<h3 v-if="type == 'grey'">添加IP到灰名单</h3>
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="listId" :value="listId"/>
|
||||
<csrf-token></csrf-token>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td>IP或IP段 *</td>
|
||||
<td>
|
||||
<input type="text" name="value" maxlength="64" placeholder="x.x.x.x" ref="focus" style="width: 20em"/>
|
||||
<p class="comment">支持IPv4和IPv6;支持三种格式:单个IP(比如192.168.1.100)、IP范围(比如192.168.1.1-192.168.1.255)、CIDR(比如192.168.1.1/24)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">过期时间</td>
|
||||
<td>
|
||||
<datetime-input :v-name="'expiredAt'"></datetime-input>
|
||||
<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>备注</td>
|
||||
<td><input type="text" name="reason" maxlength="100"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="comment">添加后将会在5分钟后生效。</p>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -0,0 +1,23 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<second-menu>
|
||||
<menu-item @click.prevent="createIP('black')">添加IP</menu-item>
|
||||
<span class="item">|</span>
|
||||
<span class="item">ID: {{listId}} <tip-icon content="ID可以用于使用API操作此IP名单"></tip-icon></span>
|
||||
</second-menu>
|
||||
|
||||
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
|
||||
|
||||
<ip-list-table v-if="items.length > 0" :v-items="items" @update-item="updateItem" @delete-item="deleteItem"></ip-list-table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
Tea.context(function () {
|
||||
this.updateItem = function (itemId) {
|
||||
teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), {
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteItem = function (itemId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个IP吗?", function () {
|
||||
that.$post(".deleteIP")
|
||||
.params({
|
||||
"listId": this.listId,
|
||||
"itemId": itemId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加IP名单菜单
|
||||
*/
|
||||
this.createIP = function (type) {
|
||||
teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
|
||||
height: "28em",
|
||||
callback: function () {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<second-menu>
|
||||
<menu-item @click.prevent="createIP('grey')">添加IP</menu-item>
|
||||
<span class="item">|</span>
|
||||
<span class="item">ID: {{listId}} <tip-icon content="ID可以用于使用API操作此IP名单;灰名单中的IP仅作为记录和观察使用,不影响黑名单和白名单的作用。"></tip-icon></span>
|
||||
</second-menu>
|
||||
|
||||
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
|
||||
|
||||
<ip-list-table v-if="items.length > 0" :v-items="items" @update-item="updateItem" @delete-item="deleteItem"></ip-list-table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
Tea.context(function () {
|
||||
this.updateItem = function (itemId) {
|
||||
teaweb.popup(Tea.url(".updateIPPopup?listId=" + this.listId, {itemId: itemId}), {
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteItem = function (itemId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个IP吗?", function () {
|
||||
that.$post(".deleteIP")
|
||||
.params({
|
||||
"listId": this.listId,
|
||||
"itemId": itemId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加IP名单菜单
|
||||
*/
|
||||
this.createIP = function (type) {
|
||||
teaweb.popup("/servers/server/settings/waf/ipadmin/createIPPopup?listId=" + this.listId + '&type=' + type, {
|
||||
height: "28em",
|
||||
callback: function () {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,36 @@
|
||||
Tea.context(function () {
|
||||
this.updateItem = function (itemId) {
|
||||
teaweb.popup(Tea.url(".updateIPPopup?firewallPolicyId=" + this.firewallPolicyId, {itemId: itemId}), {
|
||||
height: "23em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteItem = function (itemId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个IP吗?", function () {
|
||||
that.$post(".deleteIP")
|
||||
.params({
|
||||
"firewallPolicyId": this.firewallPolicyId,
|
||||
"itemId": itemId
|
||||
})
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加IP名单菜单
|
||||
*/
|
||||
this.createIP = function (type) {
|
||||
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
|
||||
height: "28em",
|
||||
callback: function () {
|
||||
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,54 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/>
|
||||
<input type="hidden" name="exceptURLPatternsJSON" :value="JSON.stringify(exceptURLPatterns)"/>
|
||||
<input type="hidden" name="onlyURLPatternsJSON" :value="JSON.stringify(onlyURLPatterns)"/>
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">仅允许的省份</td>
|
||||
<td>
|
||||
<http-firewall-province-selector :v-provinces="allowedProvinces" :v-type="'allow'" @change="changeAllowedProvinces"></http-firewall-province-selector>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">仅封禁的省份</td>
|
||||
<td>
|
||||
<p class="comment" v-if="allowedProvinces.length > 0">由于你已设置"仅允许的省份",所以不需要再设置封禁省份。</p>
|
||||
<http-firewall-province-selector :v-provinces="deniedProvinces" :v-type="'deny'" v-show="allowedProvinces.length == 0"></http-firewall-province-selector>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>例外URL <tip-icon content="对这些URL将不做任何限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="exceptURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>限制URL <tip-icon content="只对这些URL做限制。"></tip-icon></td>
|
||||
<td><url-patterns-box v-model="onlyURLPatterns"></url-patterns-box></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>提示内容</td>
|
||||
<td>
|
||||
<textarea v-model="provinceHTML" name="provinceHTML" rows="3"></textarea>
|
||||
<p class="comment">当客户端所在省份被封禁时提示页面的HTML内容;不填则表示使用默认的提示内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
|
||||
{$else}
|
||||
<server-feature-required></server-feature-required>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
Tea.context(function () {
|
||||
this.success = function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
|
||||
this.changeAllowedProvinces = function (event) {
|
||||
this.allowedProvinces = event.provinces
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
.region-letter-group .item {
|
||||
padding-left: 0.8em !important;
|
||||
padding-right: 0.8em !important;
|
||||
}
|
||||
.region-letter-group .item .count {
|
||||
font-size: 0.8em;
|
||||
color: grey;
|
||||
}
|
||||
.country-groups {
|
||||
max-height: 23em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.country-groups .country-group {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
.country-groups .country-group .country-list .item {
|
||||
float: left;
|
||||
width: 9em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.country-groups .country-group .country-list .item .checkbox label {
|
||||
font-size: 12px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.country-groups::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
/*# sourceMappingURL=selectCountriesPopup.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["selectCountriesPopup.less"],"names":[],"mappings":"AAAA,oBACC;EACC,mBAAA;EACA,oBAAA;;AAHF,oBACC,MAIC;EACC,gBAAA;EACA,WAAA;;AAKH;EACC,gBAAA;EACA,gBAAA;;AAFD,eAIC;EACC,mBAAA;;AALF,eAIC,eAGC,cACC;EACC,WAAA;EACA,UAAA;EACA,oBAAA;;AAXJ,eAIC,eAGC,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA;;AAOL,eAAe;EACd,UAAA","file":"selectCountriesPopup.css"}
|
||||
@@ -0,0 +1,59 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3 v-show="type == 'allow'">选择允许的区域</h3>
|
||||
<h3 v-show="type == 'deny'">选择封禁的区域</h3>
|
||||
<form class="ui form">
|
||||
<div class="ui menu tabular tiny region-letter-group attached">
|
||||
<a href="" v-for="group in letterGroups" class="item" :class="{active: group.code == selectedGroup, disabled: group.countMatched == 0}" @click.prevent="selectGroup(group)">{{group.code}}<span v-if="group.count > 0" class="count"> ({{group.count}})</span></a>
|
||||
<div class="item right">
|
||||
<div class="ui checkbox" @click.prevent="checkAll">
|
||||
<input type="checkbox" v-model="isCheckingAll"/>
|
||||
<label>全选</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="country-groups ui segment attached">
|
||||
<div v-for="group in letterGroups">
|
||||
<div v-if="group.code == commonGroupName && group.code == selectedGroup">
|
||||
<div class="country-group">
|
||||
<div class="country-list">
|
||||
<div class="item" v-for="country in letterCountries[commonGroupName]">
|
||||
<div class="ui checkbox" @click.prevent="selectCountry(country)">
|
||||
<input type="checkbox" v-model="country.isChecked"/>
|
||||
<label><span :class="{blue: country.isMatched}">{{country.name}}</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-for="letter in group.code" v-if="letterCountries[letter] != null && group.code == selectedGroup" class="country-group">
|
||||
<h4>{{letter}}</h4>
|
||||
<div class="country-list">
|
||||
<div class="item" v-for="country in letterCountries[letter]">
|
||||
<div class="ui checkbox" @click.prevent="selectCountry(country)">
|
||||
<input type="checkbox" v-model="country.isChecked"/>
|
||||
<label><span :class="{blue: country.isMatched}">{{country.name}}</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="margin"></div>
|
||||
<div class="ui menu text basic">
|
||||
<div class="item">
|
||||
<button class="ui button primary" @click.prevent="submit">确定</button>
|
||||
</div>
|
||||
<div class="item right" v-show="!searchBoxVisible">
|
||||
<a href="" @click.prevent="showSearchBox"><i class="icon search"></i></a>
|
||||
</div>
|
||||
<div class="item right" v-show="searchBoxVisible">
|
||||
<search-box placeholder="关键词" ref="searchBox" @change="changeKeyword"></search-box>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,197 @@
|
||||
Tea.context(function () {
|
||||
var commonGroupName = "常用"
|
||||
this.letterGroups = [
|
||||
{
|
||||
"code": commonGroupName,
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "ABC",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "DEF",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "GHI",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "JKL",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "MNO",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "PQR",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "STU",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "VWX",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
},
|
||||
{
|
||||
"code": "YZ",
|
||||
"count": 0,
|
||||
"countMatched": 0
|
||||
}
|
||||
]
|
||||
this.commonGroupName = commonGroupName
|
||||
this.selectedGroup = commonGroupName
|
||||
this.letterCountries = {}
|
||||
let that = this
|
||||
this.countSelectedCountries = this.countries.$count(function (k, country) {
|
||||
return country.isChecked
|
||||
})
|
||||
this.countries.forEach(function (country) {
|
||||
// letter
|
||||
if (typeof (that.letterCountries[country.letter]) == "undefined") {
|
||||
that.letterCountries[country.letter] = []
|
||||
}
|
||||
that.letterCountries[country.letter].push(country)
|
||||
|
||||
// common
|
||||
if (country.isCommon) {
|
||||
if (typeof that.letterCountries[commonGroupName] == "undefined") {
|
||||
that.letterCountries[commonGroupName] = []
|
||||
}
|
||||
that.letterCountries[commonGroupName].push(country)
|
||||
}
|
||||
})
|
||||
this.isCheckingAll = false
|
||||
|
||||
this.$delay(function () {
|
||||
this.change()
|
||||
})
|
||||
|
||||
this.checkAll = function () {
|
||||
this.isCheckingAll = !this.isCheckingAll
|
||||
|
||||
this.countries.forEach(function (country) {
|
||||
country.isChecked = that.isCheckingAll
|
||||
})
|
||||
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.selectGroup = function (group) {
|
||||
this.selectedGroup = group.code
|
||||
}
|
||||
|
||||
this.selectCountry = function (country) {
|
||||
country.isChecked = !country.isChecked
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.deselectCountry = function (country) {
|
||||
country.isChecked = false
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.change = function () {
|
||||
let that = this
|
||||
this.letterGroups.forEach(function (group) {
|
||||
group.count = 0
|
||||
group.countMatched = 0
|
||||
})
|
||||
this.countries.forEach(function (country) {
|
||||
that.letterGroups.forEach(function (group) {
|
||||
if (group.code.indexOf(country.letter) >= 0 || (group.code == commonGroupName && country.isCommon)) {
|
||||
if (country.isChecked) {
|
||||
group.count++
|
||||
}
|
||||
if (that.matchCountry(country)) {
|
||||
country.isMatched = (that.keyword.length > 0)
|
||||
group.countMatched++
|
||||
} else {
|
||||
country.isMatched = false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.submit = function () {
|
||||
let selectedCountries = []
|
||||
this.countries.forEach(function (country) {
|
||||
if (country.isChecked) {
|
||||
selectedCountries.push(country)
|
||||
}
|
||||
})
|
||||
NotifyPopup({
|
||||
code: 200,
|
||||
data: {
|
||||
selectedCountries: selectedCountries
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* searching
|
||||
*/
|
||||
this.searchBoxVisible = false
|
||||
this.keyword = ""
|
||||
|
||||
this.showSearchBox = function () {
|
||||
this.searchBoxVisible = true
|
||||
this.$delay(function () {
|
||||
this.$refs.searchBox.focus()
|
||||
})
|
||||
}
|
||||
|
||||
this.changeKeyword = function (event) {
|
||||
this.keyword = event.value.trim()
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.matchCountry = function (country) {
|
||||
if (this.keyword.length == 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (teaweb.match(country.name, this.keyword)) {
|
||||
return true
|
||||
}
|
||||
if (country.pinyin != null && country.pinyin.length > 0) {
|
||||
let matched = false
|
||||
let that = this
|
||||
country.pinyin.forEach(function (code) {
|
||||
if (teaweb.match(code, that.keyword)) {
|
||||
matched = true
|
||||
}
|
||||
})
|
||||
if (matched) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (country.codes != null && country.codes.length > 0) {
|
||||
let matched = false
|
||||
let that = this
|
||||
country.codes.forEach(function (code) {
|
||||
if (teaweb.match(code, that.keyword)) {
|
||||
matched = true
|
||||
}
|
||||
})
|
||||
if (matched) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
.region-letter-group {
|
||||
.item {
|
||||
padding-left: 0.8em !important;
|
||||
padding-right: 0.8em !important;
|
||||
|
||||
.count {
|
||||
font-size: 0.8em;
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.country-groups {
|
||||
max-height: 23em;
|
||||
overflow-y: auto;
|
||||
|
||||
.country-group {
|
||||
padding-bottom: 1em;
|
||||
|
||||
.country-list {
|
||||
.item {
|
||||
float: left;
|
||||
width: 9em;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.checkbox label {
|
||||
font-size: 12px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.country-groups::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
.province-list .item {
|
||||
float: left;
|
||||
width: 12em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.province-list .item .checkbox label {
|
||||
font-size: 12px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
/*# sourceMappingURL=selectProvincesPopup.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["selectProvincesPopup.less"],"names":[],"mappings":"AAAA,cACC;EACC,WAAA;EACA,WAAA;EACA,oBAAA;;AAJF,cACC,MAKC,UAAU;EACT,0BAAA;EACA,0BAAA","file":"selectProvincesPopup.css"}
|
||||
@@ -0,0 +1,32 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3 v-show="type == 'allow'">选择允许的省份</h3>
|
||||
<h3 v-show="type == 'deny'">选择封禁的省份</h3>
|
||||
|
||||
<form class="ui form">
|
||||
<table class="ui table">
|
||||
<tr>
|
||||
<td>
|
||||
<first-menu>
|
||||
<div class="item right">
|
||||
<div class="ui checkbox" @click.prevent="checkAll">
|
||||
<input type="checkbox" v-model="isCheckingAll"/>
|
||||
<label>全选</label>
|
||||
</div>
|
||||
</div>
|
||||
</first-menu>
|
||||
|
||||
<div class="province-list" style="margin-top:0.5em">
|
||||
<div class="item" v-for="province in provinces">
|
||||
<div class="ui checkbox" @click.prevent="selectProvince(province)">
|
||||
<input type="checkbox" v-model="province.isChecked"/>
|
||||
<label>{{province.name}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button class="ui button primary" type="button" @click.prevent="submit">确定</button>
|
||||
</form>
|
||||
@@ -0,0 +1,46 @@
|
||||
Tea.context(function () {
|
||||
this.isCheckingAll = false
|
||||
|
||||
this.countSelectedProvinces = this.provinces.$count(function (k, province) {
|
||||
return province.isChecked
|
||||
})
|
||||
|
||||
this.selectProvince = function (province) {
|
||||
province.isChecked = !province.isChecked
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.deselectProvince = function (province) {
|
||||
province.isChecked = false
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.checkAll = function () {
|
||||
this.isCheckingAll = !this.isCheckingAll
|
||||
let that = this
|
||||
this.provinces.forEach(function (province) {
|
||||
province.isChecked = that.isCheckingAll
|
||||
})
|
||||
|
||||
this.change()
|
||||
}
|
||||
|
||||
this.change = function () {
|
||||
|
||||
}
|
||||
|
||||
this.submit = function () {
|
||||
let selectedProvinces = []
|
||||
this.provinces.forEach(function (province) {
|
||||
if (province.isChecked) {
|
||||
selectedProvinces.push(province)
|
||||
}
|
||||
})
|
||||
NotifyPopup({
|
||||
code: 200,
|
||||
data: {
|
||||
selectedProvinces: selectedProvinces
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
.province-list {
|
||||
.item {
|
||||
float: left;
|
||||
width: 12em;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.checkbox label {
|
||||
font-size: 12px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{$layout}
|
||||
{$template "../../settings_menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "../menu"}
|
||||
|
||||
<warning-message v-if="!featureIsOn">尚未为当前用户开通此功能。</warning-message>
|
||||
|
||||
{$ if .featureIsOn}
|
||||
<warning-message v-if="!wafIsOn">当前WAF未启用,设置将在<a :href="'/servers/server/settings/waf?serverId=' + serverId">[启用Web防火墙]</a>后生效。</warning-message>
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="firewallPolicyId" :value="firewallPolicyId"/>
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">IP *</td>
|
||||
<td>
|
||||
<input type="text" name="ip" class="text" maxlength="100" ref="focus" placeholder="x.x.x.x" v-model="ip"/>
|
||||
<p class="comment">要检查的IP</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>检查结果</td>
|
||||
<td>
|
||||
<div v-if="result.isDone">
|
||||
<div v-if="!result.isOk">
|
||||
<span class="red">{{result.error}}</span>
|
||||
</div>
|
||||
<div v-if="result.isFound">
|
||||
<div v-if="result.item != null">
|
||||
<div v-if="result.isAllowed">
|
||||
<span class="green" v-if="result.item.listType == 'white'">在白名单中 <ip-item-text :v-item="result.item"></ip-item-text> <a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
|
||||
<span class="grey" v-if="result.item.listType == 'grey'">在灰名单中 <ip-item-text :v-item="result.item"></ip-item-text> <a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<span class="red">在黑名单中 <ip-item-text :v-item="result.item"></ip-item-text> <a href="" @click.prevent="updateItem(result.list.id, result.item.id)" title="查看和修改"><i class="icon pencil small"></i></a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="result.province != null">
|
||||
<span class="red">在省份封禁中 "{{result.province.name}}"</span>
|
||||
</div>
|
||||
<div v-if="result.country != null && result.province == null">
|
||||
<span class="red">在国家/地区封禁中 "{{result.country.name}}"</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!result.isFound">
|
||||
没有找到和{{ip}}匹配的配置。
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<submit-btn>检查IP状态</submit-btn>
|
||||
</form>
|
||||
{$end}
|
||||
</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
Tea.context(function () {
|
||||
this.ip = ""
|
||||
this.result = {
|
||||
isDone: false,
|
||||
isOk: false,
|
||||
isFound: false,
|
||||
isAllowed: false,
|
||||
error: "",
|
||||
province: null,
|
||||
country: null,
|
||||
ipItem: null,
|
||||
ipList: null
|
||||
}
|
||||
|
||||
this.$delay(function () {
|
||||
this.$watch("ip", function () {
|
||||
this.result.isDone = false
|
||||
})
|
||||
})
|
||||
|
||||
this.success = function (resp) {
|
||||
this.result = resp.data.result
|
||||
}
|
||||
|
||||
this.updateItem = function (listId, itemId) {
|
||||
teaweb.popup(Tea.url(".updateIPPopup?listId=" + listId, {itemId: itemId}), {
|
||||
height: "30em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改IP</h3>
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="itemId" :value="item.id"/>
|
||||
<csrf-token></csrf-token>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td>IP或IP段 *</td>
|
||||
<td>
|
||||
<input type="text" name="value" maxlength="64" placeholder="x.x.x.x" ref="focus" style="width: 20em" v-model="item.value"/>
|
||||
<p class="comment">支持IPv4和IPv6;支持三种格式:单个IP(比如192.168.1.100)、IP范围(比如192.168.1.1-192.168.1.255)、CIDR(比如192.168.1.1/24)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">过期时间</td>
|
||||
<td>
|
||||
<datetime-input :v-name="'expiredAt'" :v-timestamp="item.expiredAt"></datetime-input>
|
||||
<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>备注</td>
|
||||
<td><input type="text" name="reason" maxlength="100" v-model="item.reason"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
Reference in New Issue
Block a user