From e2351e51f0c652fc33487cfc0819f099008c539d Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 4 Sep 2023 22:56:43 -0400 Subject: [PATCH] first commit --- Makefile | 54 ++++ README.md | 0 files/etc/config/tgappstore | 304 ++++++++++++++++++ files/etc/uci-defaults/40-tgappstore | 11 + .../lua/luci/controller/admin/tgappstore.lua | 268 +++++++++++++++ .../luci/model/cbi/tgappstore/tgappstore.lua | 30 ++ .../lua/luci/view/tgappstore/tgappstore.htm | 183 +++++++++++ files/usr/share/rpcd/acl.d/tgappstore.json | 11 + 8 files changed, 861 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 files/etc/config/tgappstore create mode 100644 files/etc/uci-defaults/40-tgappstore create mode 100644 files/usr/lib/lua/luci/controller/admin/tgappstore.lua create mode 100644 files/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua create mode 100644 files/usr/lib/lua/luci/view/tgappstore/tgappstore.htm create mode 100644 files/usr/share/rpcd/acl.d/tgappstore.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9324038 --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tgappstore +PKG_VERSION=5.0.0 +PKG_RELEASE:=6 + +include $(INCLUDE_DIR)/package.mk + +define Package/tgappstore +SECTION:=luci +CATEGORY:=LuCI +SUBMENU:=3. Applications +TITLE:=LuCI appstore module by PrivateRouter +PKGARCH:=all +DEPENDS:=+luci-compat +endef + +define Package/tgappstore/description + This package contains LuCI configuration for the appstore, provided by PrivateRouter. +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/tgappstore/install + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/tgappstore + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/admin + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/tgappstore + $(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d + + $(INSTALL_CONF) ./files/etc/config/tgappstore $(1)/etc/config/tgappstore + $(INSTALL_DATA) ./files/etc/uci-defaults/40-tgappstore $(1)/etc/uci-defaults/40-tgappstore + $(INSTALL_DATA) ./files/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua $(1)/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua + $(INSTALL_DATA) ./files/usr/lib/lua/luci/controller/admin/tgappstore.lua $(1)/usr/lib/lua/luci/controller/admin/tgappstore.lua + $(INSTALL_DATA) ./files/usr/lib/lua/luci/view/tgappstore/tgappstore.htm $(1)/usr/lib/lua/luci/view/tgappstore/tgappstore.htm + $(INSTALL_DATA) ./files/usr/share/rpcd/acl.d/tgappstore.json $(1)/usr/share/rpcd/acl.d/tgappstore.json +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/files/etc/config/tgappstore b/files/etc/config/tgappstore new file mode 100644 index 0000000..c56662d --- /dev/null +++ b/files/etc/config/tgappstore @@ -0,0 +1,304 @@ +config command + option name 'Home Assistant' + option command 'opkg install luci-app-homeassistant' + option info 'Open source home automation that puts local control and privacy first.' + +config command + option name 'Jellyfin' + option command 'opkg install luci-app-jellyfin' + option info 'Jellyfin is a Free Software Media System.' + +config command + option name 'Nextcloud' + option command 'opkg install luci-app-nextcloud' + option info 'Nextcloud is a suite of self hosted file storage services like dropbox' + +config command + option name 'Emby' + option command 'opkg install luci-app-emby' + option info 'Emby is a media server designed to organize, play, and stream audio and video.' + +config command + option name 'MegaMedia' + option command 'opkg install luci-app-megamedia' + option info 'All in one installer for qbittorrent, jellyfin, jackett, raadarr, sonarr, lidarr, and prowlarr.' + +config command + option name 'Joplin' + option command 'opkg install luci-app-joplin' + option info 'Joplin is a notes and tasks app that will allow you to sync notes from the desktop application and mobile phones' + +config command + option name 'Whoogle' + option command 'opkg install luci-app-whoogle' + option info 'Get Google search results, but without any ads, javascript, AMP links, cookies, or IP address tracking.' + +config command + option name 'Motioneye' + option command 'opkg install luci-app-motioneye' + option info 'An open source IPCAM surveillance solution that is easy and ready to use.' + +config command + option name 'Plugsy' + option command 'opkg install luci-app-plugsy' + option info 'A simple dashboard used to show the status of various connected docker apps.' + +config command + option name 'Ghostblog' + option command 'opkg install luci-app-plugsy' + option info 'Ghost is a free and open source blogging platform that simplifies online publishing.' + +config command + option name 'SyncThing' + option command 'opkg install luci-app-syncthing' + option info 'Syncthing replaces proprietary sync and cloud services with something open, trustworthy and decentralized.' + +config command + option name 'qBittorrent x86' + option command 'opkg install luci-app-qbittorrent' + option info 'qBittorrent is a cross-platform free and open-source BitTorrent client compiled for OpenWRT.' + +config command + option name 'Telegram Bot' + option command 'opkg install telegrambot' + option info 'Setup your own Telegram bot for the router that allows remote reboot, client connection reports, and memory status.' + +config command + option name 'rTorrent' + option command 'opkg install luci-app-rtorrent' + option info 'rTorrent is a quick and efficient BitTorrent client that uses the libTorrent library.' + +config command + option name 'File Assistant' + option command 'opkg install luci-app-fileassistant' + option info 'A simple and easy to use file assistant tool under the NAS menu that helps navigate, edit, upload and delete files.' + +config command + option name 'Diskman' + option command 'opkg install luci-app-diskman' + option info 'A Simple Disk Manager for OpenWRT, supports disk partition and format, supports raid, btrfs-raid, and btrfs snapshot' + +config command + option name 'Router Bridge' + option command 'opkg install luci-app-bridge' + option info 'Set router as transparent bridge device that communicates with the superior routing without perception and has the function of firewall.' + +config command + option name 'NFS File Support' + option command 'opkg install luci-app-nfs' + option info 'Easy router tools to help setup local file sharing on other devices with NFS.' + +config command + option name 'File Transfer' + option command 'opkg install luci-app-filetransfer' + option info 'Simple built in router tool to help with uploading or downloading files from your router.' + +config command + option name 'mini DLNA' + option command 'opkg install luci-app-minidlna' + option info 'DLNA support for streaming media from a local folder or mounted USB drive.' + +config command + option name 'Rclone' + option command 'opkg install luci-app-rclone' + option info 'Rclone is an open source, multi threaded, web UI and program to manage or migrate content on cloud storage.' + +config command + option name 'TorGuard WireGuard' + option command 'opkg install tgwireguard' + option info 'Easy client side WireGuard support for TorGuard users. Simply copy and paste your WireGuard config.' + +config command + option name 'Samba File Sharing' + option command 'opkg install luci-app-samba4' + option info 'Setup a local folder or mounted USB drive as a shared SMB folder on your network.' + +config command + option name 'Adblock' + option command 'opkg install luci-app-adblock' + option info 'Adblocking for your Wifi router that pulls from the largest ad lists automatically.' + +config command + option name 'AdGuard Home' + option command 'opkg install adguardhome' + option info 'AdGuard Home is a free and open source network wide advertising and tracker blocker.' + +config command + option name 'Transmission' + option command 'opkg install transmission-web-control transmission-daemon transmission-remote luci-app-transmission' + option info 'Transmission is a free and open source bit torrent client that runs directly in your browser.' + +config command + option name 'Domoticz' + option command 'opkg install domoticz' + option info 'Domoticz is a Home Automation System that lets you monitor devices.' + +config command + option name 'Terminal' + option command 'opkg install luci-app-ttyd' + option info 'This is a useful Command line window tool for accessing your router within the Router Services Menu.' + +config command + option name 'Heimdall' + option command 'opkg install luci-app-heimdall' + option info 'Heimdall is a way to organise all those links to your most used web sites.' + +config command + option name 'Code Server' + option command 'opkg install luci-app-codeserver' + option info 'Code Server is a self hosted dev env you can run in the browser.' + +config command + option name 'Jackett' + option command 'opkg install luci-app-jackett' + option info 'Jackett works as a proxy server.' + +config command + option name 'LXC' + option command 'opkg install luci-app-lxc' + option info 'Deploy virtual containers with pre set templates.' + +config command + option name 'Plex' + option command 'opkg install luci-app-plex' + option info 'Plex is a media playback system that makes it simple to enjoy your media.' + +config command + option name 'WebTop' + option command 'opkg install luci-app-webtop' + option info 'Webtop is a self hosted desktop service technology that deploys a virtual desktop in the browser.' + +config command + option name 'Seafile' + option command 'opkg install luci-app-seafile' + option info 'Seafile is an open source, cross platform file hosting software system that can be synchronized.' + +config command + option name 'Bookstack' + option command 'opkg install luci-app-bookstack' + option info 'BookStack is a simple, open-source, self hosted platform for organising and storing information.' + +config command + option name 'Filebrowser' + option command 'opkg install luci-app-filebrowser' + option info 'Filebrowser is a simple web based file browser.' + +config command + option name 'MQTT broker' + option command 'opkg install luci-app-mosquitto' + option info 'Provides a webadmin for most basic mosquitto MQTT parameters for IoT and homeassistant.' + +config command + option name 'PrivateRouter Reverse Proxy' + option command 'opkg install luci-app-privaterouterproxy' + option info 'Easy router UI for setting up PrivateRouter reverse proxy to open up services or ports to the outside.' + +config command + option name 'Prowlarr' + option command 'opkg install luci-app-prowlarr' + option info 'Prowlarr is an indexer manager and proxy that works with other apps.' + +config command + option name 'SearXng' + option command 'opkg install luci-app-searxng' + option info 'SearXNG is a private internet metasearch engine which aggregates results from search services.' + +config command + option name 'Nodered' + option command 'opkg install /etc/apps/luci-app-nodered_git-23.076.66121-e78b3f9_all.ipk' + option info 'Node-RED is a flow-based development tool for visual programming.' + +config command + option name 'Alltube' + option command 'opkg install luci-app-alltube' + option info 'HTML GUI for youtube-dl' + +config command + option name 'Aria2' + option command 'opkg install aria2 luci-app-aria2 webui-aria2 ariang' + option info 'aria2 is a lightweight multi-protocol download utility with added UI support.' + +config command + option name 'Account Manager' + option command 'opkg install luci-app-acl' + option info 'Helps manage user accounts logins and passwords to various services on the router.' + +config command + option name 'Photoprism' + option command 'opkg install /etc/apps/luci-app-photoprism_230320.42282_all.ipk' + option info 'PhotoPrism is an AI Powered Photos App for the Decentralized Web.' + +config command + option name 'SimpleX' + option command 'opkg install /etc/apps/luci-app-simplex_git-23.076.66121-e78b3f9_all.ipk' + option info 'SimpleX Chat is a private and encrypted messenger without any user IDs.' + +config command + option name 'Gitea' + option command 'opkg install /etc/apps/luci-app-gitea_git-23.076.66121-e78b3f9_all.ipk' + option info 'A painless self-hosted Git service.' + +config command + option name 'Libreddit' + option command 'opkg install /etc/apps/luci-app-libreddit_git-23.076.66121-e78b3f9_all.ipk' + option info 'Libreddit is an alternative private front end to Reddit.' + +config command + option name 'Librespeed' + option command 'opkg install /etc/apps/luci-app-librespeed_git-23.076.66121-e78b3f9_all.ipk' + option info 'Free and Open Source Speedtest.' + +config command + option name 'Gotify' + option command 'opkg install /etc/apps/luci-app-gotify_git-23.076.66121-e78b3f9_all.ipk' + option info 'A simple server for sending and receiving messages in real time.' + +config command + option name 'Mastodon' + option command 'opkg install /etc/apps/luci-app-mastodon_git-23.076.66121-e78b3f9_all.ipk' + option info 'Mastodon is free platform for running a self hosted social network.' + +config command + option name 'Navidrome' + option command 'opkg install /etc/apps/luci-app-navidrome_230320.41548_all.ipk' + option info 'Navidrome is an open source music collection server and streamer.' + +config command + option name 'Neko' + option command 'opkg install /etc/apps/luci-app-neko_git-23.076.66121-e78b3f9_all.ipk' + option info 'Neko is a self hosted virtual browser and group chat.' + +config command + option name 'Owncast' + option command 'opkg install /etc/apps/luci-app-owncast_git-23.076.66121-e78b3f9_all.ipk' + option info 'Owncast is a open source live video and web chat server.' + +config command + option name 'Owntone' + option command 'opkg install /etc/apps/luci-app-owntone_230323.01598_all.ipk' + option info 'OwnTone is an open source audio server for itunes and Roku.' + +config command + option name 'Wordpress' + option command 'opkg install /etc/apps/luci-app-wordpress_git-23.076.66121-e78b3f9_all.ipk' + option info 'Wordpress is a popular website builder.' + +config command + option name 'Qbittorrent Docker' + option command 'opkg install luci-app-qbittorrentdocker' + option info 'Qbittorrent client ruinning inside docker.' + +config command + option name 'Coturn WebRTC' + option command 'opkg install coturn luci-app-coturn' + option info 'Coturn is a free open source TURN and STUN Server.' + +config command + option name 'Discourse' + option command 'opkg install /etc/apps/luci-app-discourse_git-23.076.66121-e78b3f9_all.ipk' + option info 'Discourse is a free and open source Internet forum.' + +config command + option name 'Update App List' + option command 'opkg install tgappstore' + option info 'Update your app list with the latest apps.' diff --git a/files/etc/uci-defaults/40-tgappstore b/files/etc/uci-defaults/40-tgappstore new file mode 100644 index 0000000..e63d39a --- /dev/null +++ b/files/etc/uci-defaults/40-tgappstore @@ -0,0 +1,11 @@ +touch /etc/config/tgappstore + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@tgappstore[-1] + add ucitrack tgappstore + set ucitrack.@tgappstore[-1].init=tgappstore + commit ucitrack +EOF +rm -f /tmp/luci-indexcache + +exit 0 diff --git a/files/usr/lib/lua/luci/controller/admin/tgappstore.lua b/files/usr/lib/lua/luci/controller/admin/tgappstore.lua new file mode 100644 index 0000000..36c69e1 --- /dev/null +++ b/files/usr/lib/lua/luci/controller/admin/tgappstore.lua @@ -0,0 +1,268 @@ +-- Copyright 2012 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.admin.tgappstore", package.seeall) + +function index() + entry({"admin", "apps", "tgappstore"}, firstchild(), _("Install Apps"), 80).acl_depends = { "tgappstore" } + entry({"admin", "apps", "tgappstore", "dashboard"}, template("tgappstore/tgappstore"), _("Select App"), 1) + entry({"admin", "apps", "tgappstore", "config"}, cbi("tgappstore/tgappstore"), _("Configure"), 2) + entry({"admin", "apps", "tgappstore", "run"}, call("action_run"), nil, 3).leaf = true + entry({"admin", "apps", "tgappstore", "download"}, call("action_download"), nil, 3).leaf = true + entry({"command"}, call("action_public"), nil, 1).leaf = true +end + +--- Decode a given string into arguments following shell quoting rules +--- [[abc \def "foo\"bar" abc'def']] -> [[abc def]] [[foo"bar]] [[abcdef]] +local function parse_args(str) + local args = { } + + local function isspace(c) + if c == 9 or c == 10 or c == 11 or c == 12 or c == 13 or c == 32 then + return c + end + end + + local function isquote(c) + if c == 34 or c == 39 or c == 96 then + return c + end + end + + local function isescape(c) + if c == 92 then + return c + end + end + + local function ismeta(c) + if c == 36 or c == 92 or c == 96 then + return c + end + end + + --- Convert given table of byte values into a Lua string and append it to + --- the "args" table. Segment byte value sequence into chunks of 256 values + --- to not trip over the parameter limit for string.char() + local function putstr(bytes) + local chunks = { } + local csz = 256 + local upk = unpack + local chr = string.char + local min = math.min + local len = #bytes + local off + + for off = 1, len, csz do + chunks[#chunks+1] = chr(upk(bytes, off, min(off + csz - 1, len))) + end + + args[#args+1] = table.concat(chunks) + end + + --- Scan substring defined by the indexes [s, e] of the string "str", + --- perform unquoting and de-escaping on the fly and store the result in + --- a table of byte values which is passed to putstr() + local function unquote(s, e) + local off, esc, quote + local res = { } + + for off = s, e do + local byte = str:byte(off) + local q = isquote(byte) + local e = isescape(byte) + local m = ismeta(byte) + + if e then + esc = true + elseif esc then + if m then res[#res+1] = 92 end + res[#res+1] = byte + esc = false + elseif q and quote and q == quote then + quote = nil + elseif q and not quote then + quote = q + else + if m then res[#res+1] = 92 end + res[#res+1] = byte + end + end + + putstr(res) + end + + --- Find substring boundaries in "str". Ignore escaped or quoted + --- whitespace, pass found start- and end-index for each substring + --- to unquote() + local off, esc, start, quote + for off = 1, #str + 1 do + local byte = str:byte(off) + local q = isquote(byte) + local s = isspace(byte) or (off > #str) + local e = isescape(byte) + + if esc then + esc = false + elseif e then + esc = true + elseif q and quote and q == quote then + quote = nil + elseif q and not quote then + start = start or off + quote = q + elseif s and not quote then + if start then + unquote(start, off - 1) + start = nil + end + else + start = start or off + end + end + + --- If the "quote" is still set we encountered an unfinished string + if quote then + unquote(start, #str) + end + + return args +end + +local function parse_cmdline(cmdid, args) + local uci = require "luci.model.uci".cursor() + if uci:get("tgappstore", cmdid) == "command" then + local cmd = uci:get_all("tgappstore", cmdid) + local argv = parse_args(cmd.command) + local i, v + + if cmd.param == "1" and args then + for i, v in ipairs(parse_args(luci.http.urldecode(args))) do + argv[#argv+1] = v + end + end + + for i, v in ipairs(argv) do + if v:match("[^%w%.%-i/|]") then + argv[i] = '"%s"' % v:gsub('"', '\\"') + end + end + + return argv + end +end + +function execute_command(callback, ...) + local fs = require "nixio.fs" + local argv = parse_cmdline(...) + if argv then + local outfile = os.tmpname() + local errfile = os.tmpname() + + local rv = os.execute(table.concat(argv, " ") .. " >%s 2>%s" %{ outfile, errfile }) + local stdout = fs.readfile(outfile, 1024 * 512) or "" + local stderr = fs.readfile(errfile, 1024 * 512) or "" + + fs.unlink(outfile) + fs.unlink(errfile) + + local binary = not not (stdout:match("[%z\1-\8\14-\31]")) + + callback({ + ok = true, + command = table.concat(argv, " "), + stdout = not binary and stdout, + stderr = stderr, + exitcode = rv, + binary = binary + }) + else + callback({ + ok = false, + code = 404, + reason = "No such command" + }) + end +end + +function return_json(result) + if result.ok then + luci.http.prepare_content("application/json") + luci.http.write_json(result) + else + luci.http.status(result.code, result.reason) + end +end + +function action_run(...) + execute_command(return_json, ...) +end + +function return_html(result) + if result.ok then + require("luci.template") + luci.template.render("commands_public", { + exitcode = result.exitcode, + stdout = result.stdout, + stderr = result.stderr + }) + else + luci.http.status(result.code, result.reason) + end + +end + +function action_download(...) + local fs = require "nixio.fs" + local argv = parse_cmdline(...) + if argv then + local fd = io.popen(table.concat(argv, " ") .. " 2>/dev/null") + if fd then + local chunk = fd:read(4096) or "" + local name + if chunk:match("[%z\1-\8\14-\31]") then + luci.http.header("Content-Disposition", "attachment; filename=%s" + % fs.basename(argv[1]):gsub("%W+", ".") .. ".bin") + luci.http.prepare_content("application/octet-stream") + else + luci.http.header("Content-Disposition", "attachment; filename=%s" + % fs.basename(argv[1]):gsub("%W+", ".") .. ".txt") + luci.http.prepare_content("text/plain") + end + + while chunk do + luci.http.write(chunk) + chunk = fd:read(4096) + end + + fd:close() + else + luci.http.status(500, "Failed to execute command") + end + else + luci.http.status(404, "No such command") + end +end + + +function action_public(cmdid, args) + local disp = false + if string.sub(cmdid, -1) == "s" then + disp = true + cmdid = string.sub(cmdid, 1, -2) + end + local uci = require "luci.model.uci".cursor() + if cmdid and + uci:get("tgappstore", cmdid) == "command" and + uci:get("tgappstore", cmdid, "public") == "1" + then + if disp then + luci.util.perror("blah blah") + execute_command(return_html, cmdid, args) + else + action_download(cmdid, args) + end + else + luci.http.status(403, "Access to command denied") + end + end diff --git a/files/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua b/files/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua new file mode 100644 index 0000000..31c2382 --- /dev/null +++ b/files/usr/lib/lua/luci/model/cbi/tgappstore/tgappstore.lua @@ -0,0 +1,30 @@ +-- Copyright 2012 Jo-Philipp Wich +-- Licensed to the public under the Apache License 2.0. + +local m, s + +m = Map("luci", translate("Router Appstore"), + translate("This page allows you download apps to your router and deploy with custom settings.")) + +s = m:section(TypedSection, "command", "") +s.template = "cbi/tblsection" +s.anonymous = true +s.addremove = true + + +s:option(Value, "name", translate("Description"), + translate("A short textual description of the app")) + +s:option(Value, "info", translate("App Info"), + translate("Provide Info about the app")) + +s:option(Value, "command", translate("Command"), + translate("command to install luci app")) + +s:option(Flag, "param", translate("Custom arguments"), + translate("Allow the user to provide additional command line arguments")) + +s:option(Flag, "public", translate("Public access"), + translate("Allow executing the command and downloading its output without prior authentication")) + +return m diff --git a/files/usr/lib/lua/luci/view/tgappstore/tgappstore.htm b/files/usr/lib/lua/luci/view/tgappstore/tgappstore.htm new file mode 100644 index 0000000..4852890 --- /dev/null +++ b/files/usr/lib/lua/luci/view/tgappstore/tgappstore.htm @@ -0,0 +1,183 @@ +<%# + Copyright 2012 Jo-Philipp Wich + Licensed to the public under the Apache License 2.0. +-%> + +<% css = [[ + +.commandbox { + height: 20em; + width: 30%; + float: left; + height: 20em; + margin: 5px; + position: relative; +} + +.commandbox h3 { + font-size: 1.5em !important; + line-height: 2em !important; + margin: 0 !important; +} + +.commandbox input[type="text"] { + width: 50% !important; +} + +.commandbox div { + position: absolute; + left: 0; + bottom: 1.5em; +} + +]] -%> + +<%+header%> + + + +<% + local uci = require "luci.model.uci".cursor() + local commands = { } + + uci:foreach("tgappstore", "command", function(s) commands[#commands+1] = s end) +%> + +
+
+

<%:Select App to Install%>

+ <% if #commands == 0 then %> +
+
+
+

+ <%:This section contains no values yet%> +

+
+
+
+ <% else %> +
+ <% local _, command; for _, command in ipairs(commands) do %> +
+

<%=pcdata(command.name)%>

+

<%=pcdata(command.info)%>

+ <% if command.param == "1" then %> +

<%:Arguments:%>

+ <% end %> +
+ +
+
+ <% end %> + +

+ +
+ <% end %> + +
+ + +
+ +<%+footer%> diff --git a/files/usr/share/rpcd/acl.d/tgappstore.json b/files/usr/share/rpcd/acl.d/tgappstore.json new file mode 100644 index 0000000..755cfc8 --- /dev/null +++ b/files/usr/share/rpcd/acl.d/tgappstore.json @@ -0,0 +1,11 @@ +{ + "tgappstore": { + "description": "Grant UCI access for tgappstore", + "read": { + "uci": [ "luci" ] + }, + "write": { + "uci": [ "luci" ] + } + } +}