summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-openvpn/luasrc/view/openvpn
diff options
context:
space:
mode:
authorDirk Brenken <dev@brenken.org>2018-10-20 21:22:49 +0200
committerDirk Brenken <dev@brenken.org>2018-10-23 21:17:22 +0200
commit0b04912f8d495ea836d565f3536b59d030225cfa (patch)
tree143498433847d1e42e59dcc66652fbef2a3a4bbb /applications/luci-app-openvpn/luasrc/view/openvpn
parenta0cc0769d8faf38172312a376d33aec241c19126 (diff)
luci-app-openvpn: add ovpn upload support & more
* add the ability to upload ovpn files directly, incl. appropriate uci entry in openvpn config * add the ability to edit ovpn files directly ('file' mode), beside the 'basic' and 'advanced' modes for normal setups * client side checks to validate instance name & template selection, incl. online error reporting * automatically remove non-ascii characters & windows line endings from transfered ovpn file * change from after_commit to after_apply hook * remove misleading default values for Port & Protocol in Overview Signed-off-by: Dirk Brenken <dev@brenken.org>
Diffstat (limited to 'applications/luci-app-openvpn/luasrc/view/openvpn')
-rw-r--r--applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm120
-rw-r--r--applications/luci-app-openvpn/luasrc/view/openvpn/ovpn_css.htm44
-rw-r--r--applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm26
3 files changed, 170 insertions, 20 deletions
diff --git a/applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm b/applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm
index 0166de778e..09da2eb22d 100644
--- a/applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm
+++ b/applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm
@@ -1,11 +1,111 @@
-<div class="cbi-section-create">
- <% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
- <input type="text" class="cbi-section-create-name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.text" />
- <select class="cbi-section-create-name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.select">
- <%- for k, v in luci.util.kspairs(self.add_select_options) do %>
- <option value="<%=k%>"><%=luci.util.pcdata(v)%></option>
- <% end -%>
- </select>
- <input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" title="<%:Add%>" />
- <% if self.invalid_cts then %><br /><%:Invalid%></div><% end %>
+
+<script type="text/javascript">
+//<![CDATA[
+ function vpn_add()
+ {
+ var vpn_name = div_add.querySelector("#instance_name1").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()+=\[\]{};':"\\|,<>\/?]/g,'');
+ var vpn_template = div_add.querySelector("#instance_template").value;
+ var form = document.getElementsByName('cbi')[0];
+
+ if (!vpn_name || !vpn_name.length)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
+ }
+
+ document.getElementById("instance_name1").value = vpn_name;
+ if (document.getElementById("cbi-openvpn-" + vpn_name) != null)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
+ }
+
+ if (!vpn_template || !vpn_template.length)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("Please select a valid VPN template!"))%>", 2000);
+ }
+
+ if (form)
+ {
+ form.submit();
+ }
+ }
+
+ function vpn_upload()
+ {
+ var vpn_name = div_upload.querySelector("#instance_name2").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()+=\[\]{};':"\\|,<>\/?]/g,'');
+ var vpn_file = document.getElementById("ovpn_file").value;
+ var form = document.getElementsByName('cbi')[0];
+
+ if (!vpn_name || !vpn_name.length)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
+ }
+
+ document.getElementById("instance_name2").value = vpn_name;
+ if (document.getElementById("cbi-openvpn-" + vpn_name) != null)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
+ }
+
+ if (!vpn_file || !vpn_file.length)
+ {
+ return info_message(vpn_output, "<%=pcdata(translate("Please select a valid OVPN config file to upload!"))%>", 2000);
+ }
+
+ if (form)
+ {
+ form.enctype = 'multipart/form-data';
+ form.action = '<%=url('admin/services/openvpn/upload')%>';
+ form.submit();
+ }
+ }
+
+ function info_message(output, msg, timeout)
+ {
+ timeout = timeout || 0;
+ output.innerHTML = '<em>' + msg + '</em>';
+ if (timeout > 0)
+ {
+ setTimeout(function(){ output.innerHTML=""}, timeout);
+ }
+ }
+//]]>
+</script>
+
+<%+openvpn/ovpn_css%>
+
+<div class="cbi-section-node">
+ <div class="table cbi-section-table">
+ <h4><%:Template based configuration%></h4>
+ <div class="tr cbi-section-table-row" id="div_add">
+ <div class="td">
+ <input type="text" maxlength="20" placeholder="Instance name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.text" id="instance_name1" />
+ </div>
+ <div class="td">
+ <select id="instance_template" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.select">
+ <option value="" selected="selected" disabled="disabled"><%:Select template ...%></option>
+ <%- for k, v in luci.util.kspairs(self.add_select_options) do %>
+ <option value="<%=k%>"><%=luci.util.pcdata(v)%></option>
+ <% end -%>
+ </select>
+ </div>
+ <div class="td">
+ <input class="cbi-button cbi-button-add" type="submit" onclick="vpn_add(); return false;" value="<%:Add%>" title="<%:Add template based configuration%>" /><br />
+ </div>
+ </div>
+ <h4><%:OVPN configuration file upload%></h4>
+ <div class="tr cbi-section-table-row" id="div_upload">
+ <div class="td">
+ <input type="text" maxlength="20" placeholder="Instance name" name="instance_name2" id="instance_name2" />
+ </div>
+ <div class="td">
+ <input type="file" name="ovpn_file" id="ovpn_file" accept="application/x-openvpn-profile,.ovpn" />
+ </div>
+ <div class="td">
+ <input class="cbi-button cbi-button-add" type="submit" onclick="vpn_upload(); return false;" value="<%:Upload%>" title="<%:Upload ovpn file%>" />
+ </div>
+ </div>
+ </div>
+ <div class="vpn-output">
+ <span id="vpn_output"></span>
+ </div>
</div>
diff --git a/applications/luci-app-openvpn/luasrc/view/openvpn/ovpn_css.htm b/applications/luci-app-openvpn/luasrc/view/openvpn/ovpn_css.htm
new file mode 100644
index 0000000000..c7062b8d7a
--- /dev/null
+++ b/applications/luci-app-openvpn/luasrc/view/openvpn/ovpn_css.htm
@@ -0,0 +1,44 @@
+<style type="text/css">
+ h4
+ {
+ white-space: nowrap;
+ border-bottom: 0px;
+ margin: 10px 5px 5px 5px;
+ }
+ .tr
+ {
+ border: 0px;
+ text-align: left;
+ }
+ .td
+ {
+ text-align: left;
+ border-top: 0px;
+ margin: 5px;
+ }
+ .vpn-output
+ {
+ box-shadow: none;
+ margin: 10px 5px 5px 5px;
+ color: #a22;
+ }
+ textarea
+ {
+ border: 1px solid #cccccc;
+ padding: 5px;
+ font-size: 12px;
+ font-family: monospace;
+ resize: none;
+ white-space: pre;
+ overflow-wrap: normal;
+ overflow-x: scroll;
+ }
+ a
+ {
+ line-height: 1.5;
+ }
+ hr
+ {
+ margin: 0.5em 0;
+ }
+</style>
diff --git a/applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm b/applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm
index 8cb019b461..17beef0d39 100644
--- a/applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm
+++ b/applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm
@@ -4,25 +4,31 @@
Licensed to the public under the Apache License 2.0.
-%>
+<%+openvpn/ovpn_css%>
+
<div class="cbi-section">
<h3>
- <a href="<%=url('admin/services/openvpn')%>"><%:Overview%></a> &raquo;
+ <a href="<%=url('admin/services/openvpn')%>"><%:Overview%></a> &#187;
<%=luci.i18n.translatef("Instance \"%s\"", self.instance)%>
</h3>
-
- <% if self.mode == "basic" then %>
- <a href="<%=url('admin/services/openvpn/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration »%></a>
- <% else %>
- <a href="<%=url('admin/services/openvpn/basic', self.instance)%>"><%:« Switch to basic configuration%></a>
- <hr style="margin:0.5em 0" />
+ <% if self.mode == "file" then %>
+ <a href="<%=url('admin/services/openvpn/basic', self.instance)%>"><%:Switch to basic configuration%> &#187;</a><p/>
+ <a href="<%=url('admin/services/openvpn/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> &#187;</a>
+ <hr />
+ <% elseif self.mode == "basic" then %>
+ <a href="<%=url('admin/services/openvpn/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> &#187;</a><p/>
+ <a href="<%=url('admin/services/openvpn/file', self.instance)%>"><%:Switch to file based configuration%> &#187;</a>
+ <hr />
+ <% elseif self.mode == "advanced" then %>
+ <a href="<%=url('admin/services/openvpn/basic', self.instance)%>"><%:Switch to basic configuration%> &#187;</a><p/>
+ <a href="<%=url('admin/services/openvpn/file', self.instance)%>"><%:Switch to file based configuration%> &#187;</a>
+ <hr />
<%:Configuration category%>:
<% for i, c in ipairs(self.categories) do %>
<% if c == self.category then %>
<strong><%=translate(c)%></strong>
<% else %>
- <a href="<%=luci.dispatcher.build_url(
- "admin", "services", "openvpn", "advanced", self.instance, c
- )%>"><%=translate(c)%></a>
+ <a href="<%=luci.dispatcher.build_url("admin", "services", "openvpn", "advanced", self.instance, c)%>"><%=translate(c)%></a>
<% end %>
<% if next(self.categories, i) then %>|<% end %>
<% end %>