diff options
Diffstat (limited to 'applications/luci-app-frpc')
5 files changed, 559 insertions, 0 deletions
diff --git a/applications/luci-app-frpc/Makefile b/applications/luci-app-frpc/Makefile new file mode 100644 index 0000000000..90a20c4bfc --- /dev/null +++ b/applications/luci-app-frpc/Makefile @@ -0,0 +1,13 @@ +# This is free software, licensed under the Apache License, Version 2.0 + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI Support for frp client +LUCI_DEPENDS:=+frpc + +PKG_LICENSE:=Apache-2.0 +PKG_MAINTAINER:=Richard Yu <yurichard3839@gmail.com> + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js b/applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js new file mode 100644 index 0000000000..da86569f18 --- /dev/null +++ b/applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js @@ -0,0 +1,173 @@ +'use strict'; +'require ui'; +'require form'; +'require tools.widgets as widgets'; + +// [Widget, Option, Title, Description, {Param: 'Value'}], +var startupConf = [ + [form.Flag, 'stdout', _('Log stdout')], + [form.Flag, 'stderr', _('Log stderr')], + [widgets.UserSelect, 'user', _('Run daemon as user')], + [widgets.GroupSelect, 'group', _('Run daemon as group')], + [form.Flag, 'respawn', _('Respawn when crashed')], + [form.DynamicList, 'env', _('Environment variable'), _('OS environments pass to frp for config file template, see <a href="https://github.com/fatedier/frp#configuration-file-template">frp README</a>'), {placeholder: 'ENV_NAME=value'}], + [form.DynamicList, 'conf_inc', _('Additional configs'), _('Config files include in temporary config file'), {placeholder: '/etc/frp/frpc.d/frpc_full.ini'}] +]; + +var commonConf = [ + [form.Value, 'server_addr', _('Server address'), _('ServerAddr specifies the address of the server to connect to.<br>By default, this value is "0.0.0.0".'), {datatype: 'ipaddr'}], + [form.Value, 'server_port', _('Server port'), _('ServerPort specifies the port to connect to the server on.<br>By default, this value is 7000.'), {datatype: 'port'}], + [form.Value, 'http_proxy', _('HTTP proxy'), _('HttpProxy specifies a proxy address to connect to the server through. If this value is "", the server will be connected to directly.<br>By default, this value is read from the "http_proxy" environment variable.')], + [form.ListValue, 'log_level', _('Log level'), _('LogLevel specifies the minimum log level. Valid values are "trace", "debug", "info", "warn", and "error".<br>By default, this value is "info".'), {values: ['trace', 'debug', 'info', 'warn', 'error']}], + [form.Flag, 'disable_log_color', _('Disable log color'), _('DisableLogColor disables log colors when LogWay == "console" when set to true.'), {datatype: 'bool', default: 'true'}], + [form.Value, 'token', _('Token'), _('Token specifies the authorization token used to create keys to be sent to the server. The server must have a matching token for authorization to succeed. <br>By default, this value is "".')], + [form.Value, 'admin_addr', _('Admin address'), _('AdminAddr specifies the address that the admin server binds to.<br>By default, this value is "127.0.0.1".'), {datatype: 'ipaddr'}], + [form.Value, 'admin_port', _('Admin port'), _('AdminPort specifies the port for the admin server to listen on. If this value is 0, the admin server will not be started.<br>By default, this value is 0.'), {datatype: 'port'}], + [form.Value, 'admin_user', _('Admin user'), _('AdminUser specifies the username that the admin server will use for login.<br>By default, this value is "admin".')], + [form.Value, 'admin_pwd', _('Admin password'), _('AdminPwd specifies the password that the admin server will use for login.<br>By default, this value is "admin".'), {password: true}], + [form.Value, 'assets_dir', _('Assets dir'), _('AssetsDir specifies the local directory that the admin server will load resources from. If this value is "", assets will be loaded from the bundled executable using statik.<br>By default, this value is "".')], + [form.Flag, 'tcp_mux', _('TCP mux'), _('TcpMux toggles TCP stream multiplexing. This allows multiple requests from a client to share a single TCP connection. If this value is true, the server must have TCP multiplexing enabled as well.<br>By default, this value is true.'), {datatype: 'bool', default: 'true'}], + [form.Value, 'user', _('User'), _('User specifies a prefix for proxy names to distinguish them from other clients. If this value is not "", proxy names will automatically be changed to "{user}.{proxy_name}".<br>By default, this value is "".')], + [form.Flag, 'login_fail_exit', _('Exit when login fail'), _('LoginFailExit controls whether or not the client should exit after a failed login attempt. If false, the client will retry until a login attempt succeeds.<br>By default, this value is true.'), {datatype: 'bool', default: 'true'}], + [form.ListValue, 'protocol', _('Protocol'), _('Protocol specifies the protocol to use when interacting with the server. Valid values are "tcp", "kcp", and "websocket".<br>By default, this value is "tcp".'), {values: ['tcp', 'kcp', 'websocket']}], + [form.Flag, 'tls_enable', _('TLS'), _('TLSEnable specifies whether or not TLS should be used when communicating with the server.'), {datatype: 'bool'}], + [form.Value, 'heartbeat_interval', _('Heartbeat interval'), _('HeartBeatInterval specifies at what interval heartbeats are sent to the server, in seconds. It is not recommended to change this value.<br>By default, this value is 30.'), {datatype: 'uinteger'}], + [form.Value, 'heartbeat_timeout', _('Heartbeat timeout'), _('HeartBeatTimeout specifies the maximum allowed heartbeat response delay before the connection is terminated, in seconds. It is not recommended to change this value.<br>By default, this value is 90.'), {datatype: 'uinteger'}] +]; + +var baseProxyConf = [ + [form.ListValue, 'type', _('Proxy type'), _('ProxyType specifies the type of this proxy. Valid values include "tcp", "udp", "http", "https", "stcp", and "xtcp".<br>By default, this value is "tcp".'), {values: ['tcp', 'udp', 'http', 'https', 'stcp', 'xtcp']}], + [form.Flag, 'use_encryption', _('Encryption'), _('UseEncryption controls whether or not communication with the server will be encrypted. Encryption is done using the tokens supplied in the server and client configuration.<br>By default, this value is false.'), {datatype: 'bool'}], + [form.Flag, 'use_compression', _('Compression'), _('UseCompression controls whether or not communication with the server will be compressed.<br>By default, this value is false.'), {datatype: 'bool'}], + [form.Value, 'local_ip', _('Local IP'), _('LocalIp specifies the IP address or host name to proxy to.'), {datatype: 'ipaddr'}], + [form.Value, 'local_port', _('Local port'), _('LocalPort specifies the port to proxy to.'), {datatype: 'port'}], +]; + +var bindInfoConf = [ + [form.Value, 'remote_port', _('Remote port'), _('If remote_port is 0, frps will assign a random port for you'), {datatype: 'port'}] +]; + +var domainConf = [ + [form.Value, 'custom_domains', _('Custom domains')], + [form.Value, 'sub_domain', _('Subdomain')], +]; + +var httpProxyConf = [ + [form.Value, 'locations', _('Locations')], + [form.Value, 'http_user', _('HTTP user')], + [form.Value, 'http_pwd', _('HTTP password')], + [form.Value, 'host_header_rewrite', _('Host header rewrite')], + // [form.Value, 'headers', _('Headers')], // FIXME +]; + +var stcpProxyConf = [ + [form.ListValue, 'role', _('Role'), undefined, {values: ['server', 'visitor']}], + [form.Value, 'sk', _('Sk')], +]; + +function setParams(o, params) { + if (!params) return; + for (var key in params) { + var val = params[key]; + if (key === 'values') { + for (var j = 0; j < val.length; j++) { + var args = val[j]; + if (!Array.isArray(args)) + args = [args]; + o.value.apply(o, args); + } + } else if (key === 'depends') { + if (!Array.isArray(val)) + val = [val]; + for (var j = 0; j < val.length; j++) { + var args = val[j]; + if (!Array.isArray(args)) + args = [args]; + o.depends.apply(o, args); + } + } else { + o[key] = params[key]; + } + } + if (params['datatype'] === 'bool') { + o.enabled = 'true'; + o.disabled = 'false'; + } +} + +function defTabOpts(s, t, opts, params) { + for (var i = 0; i < opts.length; i++) { + var opt = opts[i]; + var o = s.taboption(t, opt[0], opt[1], opt[2], opt[3]); + setParams(o, opt[4]); + setParams(o, params); + } +} + +function defOpts(s, opts, params) { + for (var i = 0; i < opts.length; i++) { + var opt = opts[i]; + var o = s.option(opt[0], opt[1], opt[2], opt[3]); + setParams(o, opt[4]); + setParams(o, params); + } +} + +return L.view.extend({ + render: function() { + var m, s, o; + + m = new form.Map('frpc', _('frp Client')); + + s = m.section(form.NamedSection, 'common', 'conf'); + s.dynamic = true; + + s.tab('common', _('Common Settings')); + s.tab('init', _('Startup Settings')); + + defTabOpts(s, 'common', commonConf, {optional: true}); + + o = s.taboption('init', form.SectionValue, 'init', form.TypedSection, 'init', _('Startup Settings')); + s = o.subsection; + s.anonymous = true; + s.dynamic = true; + + defOpts(s, startupConf); + + s = m.section(form.GridSection, 'conf', _('Proxy Settings')); + s.addremove = true; + s.filter = function(s) { return s !== 'common'; }; + s.renderSectionAdd = function(extra_class) { + var el = form.GridSection.prototype.renderSectionAdd.apply(this, arguments), + nameEl = el.querySelector('.cbi-section-create-name'); + ui.addValidator(nameEl, 'uciname', true, function(v) { + if (v === 'common') return _('Name can not be "common"'); + return true; + }, 'blur', 'keyup'); + return el; + } + + s.tab('general', _('General Settings')); + s.tab('http', _('HTTP Settings')); + + s.option(form.Value, 'type', _('Proxy type')).modalonly = false; + s.option(form.Value, 'local_ip', _('Local IP')).modalonly = false; + s.option(form.Value, 'local_port', _('Local port')).modalonly = false; + + defTabOpts(s, 'general', baseProxyConf, {modalonly: true}); + + // TCP and UDP + defTabOpts(s, 'general', bindInfoConf, {optional: true, modalonly: true, depends: [{type: 'tcp'}, {type: 'udp'}]}); + + // HTTP and HTTPS + defTabOpts(s, 'http', domainConf, {optional: true, modalonly: true, depends: [{type: 'http'}, {type: 'https'}]}); + + // HTTP + defTabOpts(s, 'http', httpProxyConf, {optional: true, modalonly: true, depends: {type: 'http'}}); + + // STCP and XTCP + defTabOpts(s, 'general', stcpProxyConf, {modalonly: true, depends: [{type: 'stcp'}, {type: 'xtcp'}]}); + + return m.render(); + } +}); diff --git a/applications/luci-app-frpc/po/templates/frpc.pot b/applications/luci-app-frpc/po/templates/frpc.pot new file mode 100644 index 0000000000..a9c9569239 --- /dev/null +++ b/applications/luci-app-frpc/po/templates/frpc.pot @@ -0,0 +1,356 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:14 +msgid "Additional configs" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:24 +msgid "Admin address" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:27 +msgid "Admin password" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:25 +msgid "Admin port" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:26 +msgid "Admin user" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:24 +msgid "" +"AdminAddr specifies the address that the admin server binds to.<br>By " +"default, this value is \"127.0.0.1\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:25 +msgid "" +"AdminPort specifies the port for the admin server to listen on. If this " +"value is 0, the admin server will not be started.<br>By default, this value " +"is 0." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:27 +msgid "" +"AdminPwd specifies the password that the admin server will use for login." +"<br>By default, this value is \"admin\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:26 +msgid "" +"AdminUser specifies the username that the admin server will use for login." +"<br>By default, this value is \"admin\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:28 +msgid "Assets dir" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:28 +msgid "" +"AssetsDir specifies the local directory that the admin server will load " +"resources from. If this value is \"\", assets will be loaded from the " +"bundled executable using statik.<br>By default, this value is \"\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:125 +msgid "Common Settings" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:41 +msgid "Compression" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:14 +msgid "Config files include in temporary config file" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:51 +msgid "Custom domains" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:22 +msgid "Disable log color" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:22 +msgid "" +"DisableLogColor disables log colors when LogWay == \"console\" when set to " +"true." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:40 +msgid "Encryption" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:13 +msgid "Environment variable" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:31 +msgid "Exit when login fail" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:150 +msgid "General Settings" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:151 +msgid "HTTP Settings" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:58 +msgid "HTTP password" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:20 +msgid "HTTP proxy" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:57 +msgid "HTTP user" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:60 +msgid "Headers" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:34 +msgid "" +"HeartBeatInterval specifies at what interval heartbeats are sent to the " +"server, in seconds. It is not recommended to change this value.<br>By " +"default, this value is 30." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:35 +msgid "" +"HeartBeatTimeout specifies the maximum allowed heartbeat response delay " +"before the connection is terminated, in seconds. It is not recommended to " +"change this value.<br>By default, this value is 90." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:34 +msgid "Heartbeat interval" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:35 +msgid "Heartbeat timeout" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:59 +msgid "Host header rewrite" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:20 +msgid "" +"HttpProxy specifies a proxy address to connect to the server through. If " +"this value is \"\", the server will be connected to directly.<br>By default, " +"this value is read from the \"http_proxy\" environment variable." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:47 +msgid "If remote_port is 0, frps will assign a random port for you" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:42 +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:154 +msgid "Local IP" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:43 +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:155 +msgid "Local port" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:42 +msgid "LocalIp specifies the IP address or host name to proxy to." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:43 +msgid "LocalPort specifies the port to proxy to." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:56 +msgid "Locations" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:21 +msgid "Log level" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:9 +msgid "Log stderr" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:8 +msgid "Log stdout" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:21 +msgid "" +"LogLevel specifies the minimum log level. Valid values are \"trace\", \"debug" +"\", \"info\", \"warn\", and \"error\".<br>By default, this value is \"info\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:31 +msgid "" +"LoginFailExit controls whether or not the client should exit after a failed " +"login attempt. If false, the client will retry until a login attempt " +"succeeds.<br>By default, this value is true." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:144 +msgid "Name can not be \"common\"" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:13 +msgid "" +"OS environments pass to frp for config file template, see <a href=\"https://" +"github.com/fatedier/frp#configuration-file-template\">frp README</a>" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:32 +msgid "Protocol" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:32 +msgid "" +"Protocol specifies the protocol to use when interacting with the server. " +"Valid values are \"tcp\", \"kcp\", and \"websocket\".<br>By default, this " +"value is \"tcp\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:137 +msgid "Proxy Settings" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:39 +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:153 +msgid "Proxy type" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:39 +msgid "" +"ProxyType specifies the type of this proxy. Valid values include \"tcp\", " +"\"udp\", \"http\", \"https\", \"stcp\", and \"xtcp\".<br>By default, this " +"value is \"tcp\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:47 +msgid "Remote port" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:12 +msgid "Respawn when crashed" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:64 +msgid "Role" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:11 +msgid "Run daemon as group" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:10 +msgid "Run daemon as user" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:18 +msgid "Server address" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:19 +msgid "Server port" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:18 +msgid "" +"ServerAddr specifies the address of the server to connect to.<br>By default, " +"this value is \"0.0.0.0\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:19 +msgid "" +"ServerPort specifies the port to connect to the server on.<br>By default, " +"this value is 7000." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:65 +msgid "Sk" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:126 +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:130 +msgid "Startup Settings" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:52 +msgid "Subdomain" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:29 +msgid "TCP mux" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:33 +msgid "TLS" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:33 +msgid "" +"TLSEnable specifies whether or not TLS should be used when communicating " +"with the server." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:29 +msgid "" +"TcpMux toggles TCP stream multiplexing. This allows multiple requests from a " +"client to share a single TCP connection. If this value is true, the server " +"must have TCP multiplexing enabled as well.<br>By default, this value is " +"true." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:23 +msgid "Token" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:23 +msgid "" +"Token specifies the authorization token used to create keys to be sent to " +"the server. The server must have a matching token for authorization to " +"succeed. <br>By default, this value is \"\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:41 +msgid "" +"UseCompression controls whether or not communication with the server will be " +"compressed.<br>By default, this value is false." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:40 +msgid "" +"UseEncryption controls whether or not communication with the server will be " +"encrypted. Encryption is done using the tokens supplied in the server and " +"client configuration.<br>By default, this value is false." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:30 +msgid "User" +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:30 +msgid "" +"User specifies a prefix for proxy names to distinguish them from other " +"clients. If this value is not \"\", proxy names will automatically be " +"changed to \"{user}.{proxy_name}\".<br>By default, this value is \"\"." +msgstr "" + +#: applications/luci-app-frpc/htdocs/luci-static/resources/view/frpc.js:120 +#: applications/luci-app-frpc/root/usr/share/luci/menu.d/luci-app-frpc.json:3 +msgid "frp Client" +msgstr "" diff --git a/applications/luci-app-frpc/root/usr/share/luci/menu.d/luci-app-frpc.json b/applications/luci-app-frpc/root/usr/share/luci/menu.d/luci-app-frpc.json new file mode 100644 index 0000000000..26a0f2b1cf --- /dev/null +++ b/applications/luci-app-frpc/root/usr/share/luci/menu.d/luci-app-frpc.json @@ -0,0 +1,9 @@ +{ + "admin/services/frpc": { + "title": "frp Client", + "action": { + "type": "view", + "path": "frpc" + } + } +} diff --git a/applications/luci-app-frpc/root/usr/share/rpcd/acl.d/luci-app-frpc.json b/applications/luci-app-frpc/root/usr/share/rpcd/acl.d/luci-app-frpc.json new file mode 100644 index 0000000000..970b95780c --- /dev/null +++ b/applications/luci-app-frpc/root/usr/share/rpcd/acl.d/luci-app-frpc.json @@ -0,0 +1,8 @@ +{ + "luci-app-frpc": { + "description": "Grant access to LuCI app frpc", + "write": { + "uci": ["frpc"] + } + } +} |