├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── feature_request.md
│ └── issue_form.yml
└── workflows
│ ├── codeql-analysis.yml
│ ├── codesee-arch-diagram.yml
│ ├── release.yml
│ └── stale.yml
├── .gitignore
├── .gitmodules
├── .travis.yml
├── BACKERS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── _config.yml
├── _layouts
└── default.html
├── ajax
├── adblock
│ └── update_blocklist.php
├── bandwidth
│ ├── get_bandwidth.php
│ └── get_bandwidth_hourly.php
├── logging
│ └── clearlog.php
├── networking
│ ├── do_sys_reset.php
│ ├── get_all_interfaces.php
│ ├── get_channel.php
│ ├── get_frequencies.php
│ ├── get_ip_summary.php
│ ├── get_netcfg.php
│ ├── get_nl80211_band.php
│ ├── get_wgcfg.php
│ ├── get_wgkey.php
│ └── wifi_stations.php
├── openvpn
│ ├── activate_ovpncfg.php
│ └── del_ovpncfg.php
├── plugins
│ └── do_plugin_install.php
├── session
│ └── do_check_session.php
└── system
│ ├── sys_actions.php
│ ├── sys_chk_update.php
│ ├── sys_debug.php
│ ├── sys_get_logfile.php
│ ├── sys_perform_update.php
│ └── sys_read_logfile.php
├── api
├── auth.py
├── main.py
├── modules
│ ├── ap.py
│ ├── client.py
│ ├── ddns.py
│ ├── dhcp.py
│ ├── dns.py
│ ├── firewall.py
│ ├── networking.py
│ ├── openvpn.py
│ ├── system.py
│ └── wireguard.py
└── requirements.txt
├── app
├── css
│ ├── all.css
│ ├── custom.php
│ ├── dark.css
│ └── hackernews.css
├── icons
│ ├── apple-touch-icon.png
│ ├── favicon-96x96.png
│ ├── favicon.ico
│ ├── favicon.svg
│ ├── site.webmanifest
│ ├── web-app-manifest-192x192.png
│ └── web-app-manifest-512x512.png
├── img
│ ├── dashed.svg
│ ├── devices
│ │ ├── compute.php
│ │ ├── default.php
│ │ └── zero.php
│ ├── insiders.png
│ ├── raspAP-logo.php
│ ├── raspAP-logo.png
│ ├── right-dashed.svg
│ ├── right-solid.php
│ ├── solid.php
│ ├── uri-qr-code.php
│ ├── wg-qr-code.php
│ └── wifi-qr-code.php
├── js
│ ├── bandwidthcharts.js
│ ├── bandwidthcharts.min.js
│ ├── custom.js
│ ├── custom.min.js
│ ├── dashboardchart.js
│ ├── huebee.js
│ └── linkquality.js
├── lib
│ └── Parsedown.php
└── pitft
│ └── stats.py
├── composer.json
├── config
├── 090_raspap.conf
├── 090_wlan0.conf
├── 50-raspap-router.conf
├── blocklists.json
├── client_config
│ ├── 70-mobile-data-sticks.rules
│ ├── 80-raspap-net-devices.rules
│ ├── huawei_hilink_api.sh
│ ├── info_huawei.sh
│ ├── info_huawei_hilink.sh
│ ├── info_huawei_modem.sh
│ ├── interfaces
│ ├── mcc-mnc-table.csv
│ ├── onoff_huawei_hilink.sh
│ ├── ppp0_route.sh
│ ├── ppp0_setpin.sh
│ ├── raspap_helpers.sh
│ ├── start_huawei_hilink@.service
│ ├── start_ppp0_device.service
│ └── wvdial.conf
├── client_udev_prototypes.json
├── config.php
├── defaults.json
├── dhcpcd.conf
├── dns-servers.json
├── hostapd.conf
├── iptables_rules.json
├── raspap-br0-member-eth0.network
├── raspap-bridge-br0.netdev
├── raspap-bridge-br0.netplan
└── vpn-providers.json
├── crowdin.yml
├── dist
├── bootstrap
│ ├── css
│ │ ├── bootstrap-grid.css
│ │ ├── bootstrap-reboot.css
│ │ ├── bootstrap.css
│ │ ├── bootstrap.css.map
│ │ └── bootstrap.min.css
│ └── js
│ │ ├── bootstrap.bundle.js
│ │ ├── bootstrap.bundle.js.map
│ │ ├── bootstrap.bundle.min.js
│ │ ├── bootstrap.bundle.min.js.map
│ │ ├── bootstrap.js
│ │ ├── bootstrap.js.map
│ │ ├── bootstrap.min.js
│ │ └── bootstrap.min.js.map
├── chart.js
│ ├── Chart.bundle.js
│ ├── Chart.bundle.min.js
│ ├── Chart.js
│ └── Chart.min.js
├── datatables
│ ├── dataTables.bootstrap4.css
│ ├── dataTables.bootstrap4.js
│ ├── dataTables.bootstrap4.min.css
│ ├── dataTables.bootstrap4.min.js
│ ├── jquery.dataTables.js
│ └── jquery.dataTables.min.js
├── font-awesome
│ ├── LICENSE.txt
│ ├── css
│ │ ├── all.css
│ │ ├── all.min.css
│ │ ├── brands.css
│ │ ├── brands.min.css
│ │ ├── fontawesome.css
│ │ ├── fontawesome.min.css
│ │ ├── regular.css
│ │ ├── regular.min.css
│ │ ├── solid.css
│ │ ├── solid.min.css
│ │ ├── svg-with-js.css
│ │ ├── svg-with-js.min.css
│ │ ├── v4-font-face.css
│ │ ├── v4-font-face.min.css
│ │ ├── v4-shims.css
│ │ ├── v4-shims.min.css
│ │ ├── v5-font-face.css
│ │ └── v5-font-face.min.css
│ ├── package.json
│ └── webfonts
│ │ ├── fa-brands-400.eot
│ │ ├── fa-brands-400.svg
│ │ ├── fa-brands-400.ttf
│ │ ├── fa-brands-400.woff
│ │ ├── fa-brands-400.woff2
│ │ ├── fa-regular-400.eot
│ │ ├── fa-regular-400.svg
│ │ ├── fa-regular-400.ttf
│ │ ├── fa-regular-400.woff
│ │ ├── fa-regular-400.woff2
│ │ ├── fa-solid-900.eot
│ │ ├── fa-solid-900.svg
│ │ ├── fa-solid-900.ttf
│ │ ├── fa-solid-900.woff
│ │ ├── fa-solid-900.woff2
│ │ ├── fa-v4compatibility.ttf
│ │ └── fa-v4compatibility.woff2
├── huebee
│ ├── huebee.css
│ ├── huebee.min.css
│ ├── huebee.pkgd.js
│ └── huebee.pkgd.min.js
├── jquery-easing
│ ├── jquery.easing.compatibility.js
│ ├── jquery.easing.js
│ └── jquery.easing.min.js
├── jquery-mask
│ └── jquery.mask.min.js
├── jquery
│ ├── jquery.js
│ ├── jquery.min.js
│ ├── jquery.min.map
│ ├── jquery.slim.js
│ ├── jquery.slim.min.js
│ └── jquery.slim.min.map
├── raspap
│ └── css
│ │ ├── fonts
│ │ ├── RaspAP.eot
│ │ ├── RaspAP.svg
│ │ ├── RaspAP.ttf
│ │ └── RaspAP.woff
│ │ └── style.css
└── sb-admin
│ ├── css
│ └── styles.css
│ └── js
│ └── scripts.js
├── favicon.ico
├── gulpfile.js
├── includes
├── CSRF.php
├── about.php
├── adblock.php
├── admin.php
├── authenticate.php
├── autoload.php
├── configure_client.php
├── dashboard.php
├── data_usage.php
├── defaults.php
├── dhcp.php
├── footer.php
├── functions.php
├── get_clients.php
├── hostapd.php
├── internetRoute.php
├── locale.php
├── login.php
├── navbar.php
├── networking.php
├── openvpn.php
├── page_actions.php
├── provider.php
├── restapi.php
├── session.php
├── sidebar.php
├── sysstats.php
├── system.php
├── wifi_functions.php
└── wireguard.php
├── index.php
├── installers
├── common.sh
├── configauth.sh
├── configport.sh
├── debuglog.sh
├── dhcpcd.service
├── disablelog.sh
├── enablelog.sh
├── install_feature_clients.sh
├── install_feature_firewall.sh
├── minwrite.sh
├── mkcert.sh
├── openvpnlog.sh
├── plugin_helper.sh
├── raspap-network-activity@.service
├── raspap-network-monitor.c
├── raspap.sudoers
├── raspapd.service
├── raspbian.sh
├── restapi.service
├── servicestart.sh
├── toggle-bridged-routed.sh
├── uninstall.sh
├── update_blocklist.sh
└── update_firewall.sh
├── locale
├── cs_CZ
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── da_DK
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── de_DE
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── el_GR
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── en_US
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── es_MX
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── fi_FI
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── fr_FR
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── id_ID
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── it_IT
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── ja_JP
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── ko_KR
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── nl_NL
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── pl_PL
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── pocompile.sh
├── pt_BR
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── ro_RO
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── ru_RU
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── sk_SK
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── sv_SE
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── tr_TR
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── vi_VN
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
├── zh_CN
│ └── LC_MESSAGES
│ │ ├── messages.mo
│ │ └── messages.po
└── zh_TW
│ └── LC_MESSAGES
│ ├── messages.mo
│ └── messages.po
├── package.json
├── src
└── RaspAP
│ ├── Auth
│ └── HTTPAuth.php
│ ├── DotEnv
│ └── DotEnv.php
│ ├── Exceptions
│ ├── ExceptionHandler.php
│ └── HtmlErrorRenderer.php
│ ├── Messages
│ └── StatusMessage.php
│ ├── Parsers
│ └── IwParser.php
│ ├── Plugins
│ ├── PluginInstaller.php
│ ├── PluginInterface.php
│ └── PluginManager.php
│ ├── System
│ └── Sysinfo.php
│ ├── Tokens
│ └── CSRFTokenizer.php
│ ├── UI
│ ├── Dashboard.php
│ └── Sidebar.php
│ └── Uploader
│ └── FileUpload.php
├── templates
├── about.php
├── about
│ ├── contributing.php
│ ├── general.php
│ └── insiders.php
├── adblock.php
├── adblock
│ ├── custom.php
│ ├── general.php
│ ├── logging.php
│ └── stats.php
├── admin.php
├── configure_client.php
├── dashboard.php
├── dashboard
│ ├── data.php
│ └── status.php
├── data_usage.php
├── dhcp.php
├── dhcp
│ ├── advanced.php
│ ├── clients.php
│ ├── general.php
│ ├── logging.php
│ └── static_leases.php
├── exception.php
├── hostapd.php
├── hostapd
│ ├── advanced.php
│ ├── basic.php
│ ├── logging.php
│ └── security.php
├── login.php
├── networking.php
├── openvpn.php
├── openvpn
│ ├── configs.php
│ ├── general.php
│ └── logging.php
├── provider.php
├── provider
│ ├── general.php
│ └── status.php
├── restapi.php
├── restapi
│ ├── general.php
│ └── status.php
├── system.php
├── system
│ ├── advanced.php
│ ├── basic.php
│ ├── language.php
│ ├── plugins.php
│ ├── theme.php
│ └── tools.php
├── torproxy.php
├── wg
│ ├── general.php
│ ├── logging.php
│ └── peers.php
├── wifi_stations.php
├── wifi_stations
│ └── network.php
└── wireguard.php
└── yarn.lock
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: RaspAP
2 |
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: RaspAP Community Support
4 | url: https://github.com/RaspAP/raspap-webgui/discussions
5 | about: Please ask and answer questions here.
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## Is your feature request related to a problem?
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | ## Describe the solution you'd like
14 | A clear and concise description of what you want to happen.
15 |
16 | ## Describe alternatives you've considered
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | ## Additional context
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '17 9 * * 1'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 |
28 | strategy:
29 | fail-fast: false
30 | matrix:
31 | language: [ 'javascript', 'python' ]
32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33 | # Learn more:
34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
35 |
36 | steps:
37 | - name: Checkout repository
38 | uses: actions/checkout@v2
39 |
40 | # Initializes the CodeQL tools for scanning.
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v1
43 | with:
44 | languages: ${{ matrix.language }}
45 | # If you wish to specify custom queries, you can do so here or in a config file.
46 | # By default, queries listed here will override any specified in a config file.
47 | # Prefix the list here with "+" to use these queries and those in the config file.
48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
49 |
50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51 | # If this step fails, then you should remove it and run the build manually (see below)
52 | - name: Autobuild
53 | uses: github/codeql-action/autobuild@v1
54 |
55 | # ℹ️ Command-line programs to run using the OS shell.
56 | # 📚 https://git.io/JvXDl
57 |
58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59 | # and modify them (or add more) to build your code if your project
60 | # uses a compiled language
61 |
62 | #- run: |
63 | # make bootstrap
64 | # make release
65 |
66 | - name: Perform CodeQL Analysis
67 | uses: github/codeql-action/analyze@v1
68 |
--------------------------------------------------------------------------------
/.github/workflows/codesee-arch-diagram.yml:
--------------------------------------------------------------------------------
1 | # This workflow was added by CodeSee. Learn more at https://codesee.io/
2 | # This is v2.0 of this workflow file
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request_target:
8 | types: [opened, synchronize, reopened]
9 |
10 | name: CodeSee
11 |
12 | permissions: read-all
13 |
14 | jobs:
15 | codesee:
16 | runs-on: ubuntu-latest
17 | continue-on-error: true
18 | name: Analyze the repo with CodeSee
19 | steps:
20 | - uses: Codesee-io/codesee-action@v2
21 | with:
22 | codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
23 | codesee-url: https://app.codesee.io
24 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Close inactive issues
2 | on:
3 | schedule:
4 | - cron: "30 1 * * *"
5 |
6 | jobs:
7 | close-issues:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | issues: write
11 | pull-requests: write
12 | steps:
13 | - uses: actions/stale@v8.0.0
14 | with:
15 | days-before-issue-stale: 30
16 | days-before-issue-close: 14
17 | stale-issue-label: "stale"
18 | stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
19 | close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
20 | exempt-issue-labels: pinned, enhancement, feature request
21 | days-before-pr-stale: -1
22 | days-before-pr-close: -1
23 | repo-token: ${{ secrets.GITHUB_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | yarn-error.log
4 | *.swp
5 | includes/config.php
6 | rootCA.pem
7 | vendor
8 | .env
9 | locale/**/*.mo
10 | app/net_activity
11 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "plugins"]
2 | path = plugins
3 | url = https://github.com/RaspAP/plugins
4 | branch = master
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: php
3 |
4 | matrix:
5 | fast_finish: true
6 |
7 | include:
8 | - php: '7.0'
9 | - php: '7.1'
10 | - php: '7.2'
11 | - php: '7.3'
12 | - php: '7.4'
13 | - php: 'nightly'
14 |
15 | allow_failures:
16 | - php: nightly
17 |
18 | before_script:
19 | - composer install --prefer-source --quiet --no-interaction
20 |
21 | # Run test script commands.
22 | script:
23 | - composer test
24 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute
2 | Everyone is invited and welcome to contribute to RaspAP. There's a lot to do — if you're not a developer we can always use help with the official [project documentation](https://docs.raspap.com) and language [translations](https://crowdin.com/project/raspap). If you have experience in Linux networking, you can share your knowledge by answering questions from RaspAP users in our [GitHub discussions](https://github.com/RaspAP/raspap-webgui/discussions) and/or the [/r/RaspAP](https://reddit.com/r/RaspAP) subreddit.
3 |
4 | If you're a devloper, the process of contributing code is straightforward:
5 |
6 | 1. Fork the project in your account and create a new branch: `feat/your-feature` or `fix/your-bugfix`.
7 | 2. Open [an issue](https://github.com/RaspAP/raspap-webgui/issues) describing the feature or bug fix contribution you'd like to make.
8 | 3. Commit changes in your branch.
9 | 4. Open a pull request and reference the initial issue in the pull request message, or by linking it in GitHub.
10 |
11 | ### Coding standards
12 | This project follows the [PSR-2](http://www.php-fig.org/psr/psr-2/) coding style guidelines. There are many ways to check your code for PSR-2. An excellent tool is [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer). The command line tool phpcs can be run against any single file. [Phing](https://www.phing.info/), a PHP build tool, integrates nicely with `phpcs` to automate PSR-2 checks across all source files in a project.
13 |
14 | ### RaspAP community
15 | RaspAP is made possible by a strong [community of developers](https://github.com/RaspAP/raspap-webgui/graphs/contributors). If you have any questions or would like to get involved in RaspAP, dive into any of these channels:
16 |
17 | * [GitHub discussions](https://github.com/RaspAP/raspap-webgui/discussions)
18 | * [Discord chat](https://discord.gg/KVAsaAR)
19 | * [Twitter](https://twitter.com/rasp_ap)
20 | * [Reddit](https://www.reddit.com/r/RaspAP/)
21 |
22 | If you enjoy using RaspAP and would like to support our work financially, consider becoming an [Insider](https://github.com/sponsors/RaspAP).
23 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | The RaspAP team and community take all security vulnerabilities seriously. This document outlines security procedures and general policies for the RaspAP open source projects as found on https://github.com/RaspAP/.
4 | If you believe you have found a security vulnerability in any RaspAP-owned repository, please report it to us as described below.
5 |
6 | ## Reporting a vulnerability in RaspAP
7 |
8 | Thank you for improving the security of our open source software.
9 | We appreciate your efforts and responsible disclosure, and will make every effort to acknowledge your contributions.
10 |
11 | Please report (suspected) security vulnerabilities to [security@raspap.com](mailto:security@raspap.com). The requested information listed below will help us better understand the nature and scope of the possible issue:
12 |
13 | 1. Type of issue (eg. shell exploit, cross-site scripting, etc.)
14 | 2. Full paths of source file(s) related to the manifestation of the issue
15 | 3. The location of the affected source code (tag/branch/commit or direct URL)
16 | 4. Any special configuration required to reproduce the issue
17 | 5. Step-by-step instructions to reproduce the issue
18 | 6. Proof-of-concept or exploit code (if possible)
19 | 7. Impact of the issue, including how an attacker might exploit the issue
20 |
21 | This information will help us triage your report more quickly.
22 |
23 | You will receive a response from us within 48 hours. Developers may ask for additional information or clarity on your report.
24 | If the issue is confirmed, we will release a patch as soon as possible depending on complexity, but historically within a few days.
25 |
26 | ## Third-party modules
27 | Report security vulnerabilities in third-party modules to the person or team maintaining the module.
28 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
--------------------------------------------------------------------------------
/ajax/adblock/update_blocklist.php:
--------------------------------------------------------------------------------
1 | $return,'list'=>$dest];
50 | echo json_encode($jsonData);
51 | } else {
52 | $jsonData = ['return'=>2,'output'=>['Error getting data']];
53 | echo json_encode($jsonData);
54 | }
55 |
--------------------------------------------------------------------------------
/ajax/bandwidth/get_bandwidth.php:
--------------------------------------------------------------------------------
1 | 0) {
13 | $interface = $interfacesWlo[0];
14 | } else {
15 | exit('No network interfaces found.');
16 | }
17 | }
18 | define('IFNAMSIZ', 16);
19 | if (strlen($interface) > IFNAMSIZ) {
20 | exit('Interface name too long.');
21 | } elseif(!preg_match('/^[a-zA-Z0-9]+$/', $interface)) {
22 | exit('Invalid interface name.');
23 | }
24 |
25 | require_once './get_bandwidth_hourly.php';
26 |
27 | exec(
28 | sprintf('vnstat -i %s --json ', escapeshellarg($interface)), $jsonstdoutvnstat,
29 | $exitcodedaily
30 | );
31 | if ($exitcodedaily !== 0) {
32 | exit('vnstat error');
33 | }
34 |
35 | $jsonobj = json_decode($jsonstdoutvnstat[0], true);
36 | $timeunits = filter_input(INPUT_GET, 'tu');
37 | if ($timeunits === 'm') {
38 | // months
39 | $jsonData = $jsonobj['interfaces'][0]['traffic']['month'];
40 | } else {
41 | // default: days
42 | $jsonData = $jsonobj['interfaces'][0]['traffic']['day'];
43 | }
44 |
45 | $datasizeunits = filter_input(INPUT_GET, 'dsu');
46 | $dsu_factor = $datasizeunits == "mb" ? 1024 * 1024 : 1024;
47 | header('X-Content-Type-Options: nosniff');
48 | header('Content-Type: application/json');
49 | echo '[ ';
50 | $firstelm = true;
51 | for ($i = count($jsonData) - 1; $i >= 0; --$i) {
52 | if ($timeunits === 'm') {
53 | $dt = DateTime::createFromFormat(
54 | 'Y n', $jsonData[$i]['date']['year'].' '.
55 | $jsonData[$i]['date']['month']
56 | );
57 | } else {
58 | $dt = DateTime::createFromFormat(
59 | 'Y n j', $jsonData[$i]['date']['year'].' '.
60 | $jsonData[$i]['date']['month'].' '.
61 | $jsonData[$i]['date']['day']
62 | );
63 | }
64 |
65 | if ($firstelm) {
66 | $firstelm = false;
67 | } else {
68 | echo ',';
69 | }
70 |
71 | $datasend = round($jsonData[$i]['tx'] / $dsu_factor, 0);
72 | $datareceived = round($jsonData[$i]['rx'] / $dsu_factor, 0);
73 |
74 | if ($timeunits === 'm') {
75 | echo '{ "date": "' , $dt->format('Y-m') , '", "rx": "' , $datareceived ,
76 | '", "tx": "' , $datasend , '" }';
77 | } else {
78 | echo '{ "date": "' , $dt->format('Y-m-d') , '", "rx": "' , $datareceived ,
79 | '", "tx": "' , $datasend , '" }';
80 | }
81 | }
82 |
83 | echo ' ]';
84 |
--------------------------------------------------------------------------------
/ajax/logging/clearlog.php:
--------------------------------------------------------------------------------
1 | $path .'/hostapd.conf', "tmp" => "/tmp/hostapddata", "dest" => RASPI_HOSTAPD_CONFIG),
13 | array("src" => $path .'/dhcpcd.conf', "tmp" => "/tmp/dhcpddata", "dest" => RASPI_DHCPCD_CONFIG),
14 | array("src" => $path .'/090_wlan0.conf', "tmp" => "/tmp/dnsmasqdata", "dest" => RASPI_DNSMASQ_PREFIX.'wlan0.conf'),
15 | array("src" => $path .'/090_raspap.conf', "tmp" => "/tmp/dnsmasqdata", "dest" => RASPI_DNSMASQ_PREFIX.'raspap.conf'),
16 | );
17 |
18 | foreach ($configs as $config) {
19 | try {
20 | $tmp = file_get_contents($config["src"]);
21 | file_put_contents($config["tmp"], $tmp);
22 | system("sudo cp ".$config["tmp"]. " ".$config["dest"]);
23 | } catch (Exception $e) {
24 | $return = $e->getCode();
25 | }
26 | }
27 | $jsonData = ['return'=>$return];
28 | echo json_encode($jsonData);
29 |
30 |
--------------------------------------------------------------------------------
/ajax/networking/get_all_interfaces.php:
--------------------------------------------------------------------------------
1 | parseIwInfo($iface);
13 |
14 | echo json_encode($supportedFrequencies);
15 | }
16 |
--------------------------------------------------------------------------------
/ajax/networking/get_ip_summary.php:
--------------------------------------------------------------------------------
1 | $intResult,'output'=>$intOutput];
14 | echo json_encode($jsonData);
15 | } else {
16 | $jsonData = ['return'=>2,'output'=>['Error getting data']];
17 | echo json_encode($jsonData);
18 | }
19 |
--------------------------------------------------------------------------------
/ajax/networking/get_nl80211_band.php:
--------------------------------------------------------------------------------
1 | 0) {
29 | $flags += NL80211_BAND_24GHZ;
30 | }
31 | if (count(preg_grep('/^5[0-9]{3}/i', $frequencies)) >0) {
32 | $flags += NL80211_BAND_5GHZ;
33 | }
34 |
35 | switch ($flags) {
36 | case NL80211_BAND_24GHZ:
37 | $msg = sprintf(_("The selected interface (%s) has support for the 2.4 GHz wireless band only."), $iface);
38 | break;
39 | case NL80211_BAND_5GHZ:
40 | $msg = sprintf(_("The selected interface (%s) has support for the 5 GHz wireless band only."), $iface);
41 | break;
42 | case NL80211_BAND_24GHZ | NL80211_BAND_5GHZ:
43 | $msg = sprintf(_("The selected interface (%s) has support for both the 2.4 and 5 GHz wireless bands."), $iface);
44 | break;
45 | default:
46 | $msg = sprintf(_("The selected interface (%s) does not support wireless mode operation."), $iface);
47 | }
48 | echo json_encode($msg);
49 | }
50 |
--------------------------------------------------------------------------------
/ajax/networking/get_wgcfg.php:
--------------------------------------------------------------------------------
1 | $pubkey_tmp", $return);
19 | $wgdata['pubkey'] = str_replace("\n",'',file_get_contents($pubkey_tmp));
20 | exec("sudo mv $privkey_tmp $privkey", $return);
21 | exec("sudo mv $pubkey_tmp $pubkey", $return);
22 |
23 | echo json_encode($wgdata);
24 | }
25 |
--------------------------------------------------------------------------------
/ajax/networking/wifi_stations.php:
--------------------------------------------------------------------------------
1 | $network) $networks[$ssid]["ssidutf8"] = ssid2utf8( $ssid );
20 |
21 | $connected = array_filter($networks, function($n) { return $n['connected']; } );
22 | $known = array_filter($networks, function($n) { return !$n['connected'] && $n['configured']; } );
23 | $nearby = array_filter($networks, function($n) { return !$n['configured']; } );
24 |
25 | echo renderTemplate('wifi_stations', compact('networks', 'connected', 'known', 'nearby'), true);
26 |
--------------------------------------------------------------------------------
/ajax/openvpn/activate_ovpncfg.php:
--------------------------------------------------------------------------------
1 | $return];
14 | echo json_encode($jsonData);
15 | }
16 |
--------------------------------------------------------------------------------
/ajax/plugins/do_plugin_install.php:
--------------------------------------------------------------------------------
1 | installPlugin($plugin_uri, $plugin_version, $install_path);
16 | echo json_encode($return);
17 | } catch (Exception $e) {
18 | http_response_code(422); // unprocessable content
19 | echo json_encode(['error' => $e->getMessage()]);
20 | }
21 | } else {
22 | http_response_code(400); // Bad Request
23 | echo json_encode(['error' => 'Plugin URI, version, and install path are required']);
24 | exit;
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/ajax/session/do_check_session.php:
--------------------------------------------------------------------------------
1 | = RASPI_SESSION_TIMEOUT ? 'session_expired' : 'active';
11 |
12 | if ($status === 'session_expired') {
13 | session_unset(); // unset all session variables
14 | session_destroy(); // destroy the session
15 | }
16 |
17 | // send response
18 | header('Content-Type: application/json');
19 | header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
20 | header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
21 | header('Pragma: no-cache');
22 |
23 | $response = [
24 | 'status' => $status,
25 | 'last_activity' => $lastActivity,
26 | 'session_lifetime' => $sessionLifetime
27 | ];
28 |
29 | echo json_encode($response);
30 | exit();
31 |
32 |
--------------------------------------------------------------------------------
/ajax/system/sys_actions.php:
--------------------------------------------------------------------------------
1 | 1,
11 | 'Updating sources' => 2,
12 | 'Installing required packages' => 3,
13 | 'Cloning latest files' => 4,
14 | 'Installing application' => 5,
15 | 'Installation completed' => 6,
16 | 'error' => 7
17 | ];
18 | usleep(500);
19 |
20 | if (file_exists($logFile)) {
21 | $handle = fopen($logFile, 'r');
22 |
23 | if ($handle) {
24 | while (($line = fgets($handle)) !== false) {
25 | foreach ($searchStrings as $searchString => $value) {
26 | if (strpos($line, $searchString) !== false) {
27 | echo $value .PHP_EOL;
28 | flush();
29 | ob_flush();
30 | if ($value === 6) {
31 | fclose($handle);
32 | exit();
33 | } elseif ($value === 7) {
34 | echo $line .PHP_EOL;
35 | fclose($handle);
36 | exit();
37 | }
38 | }
39 | }
40 | }
41 | fclose($handle);
42 | } else {
43 | echo json_encode("Unable to open file: $logFile");
44 | }
45 | } else {
46 | echo json_encode("File does not exist: $logFile");
47 | }
48 |
--------------------------------------------------------------------------------
/api/auth.py:
--------------------------------------------------------------------------------
1 | import os
2 | from fastapi.security.api_key import APIKeyHeader
3 | from fastapi import Security, HTTPException
4 | from starlette.status import HTTP_403_FORBIDDEN
5 | from dotenv import load_dotenv
6 |
7 | load_dotenv()
8 |
9 | apikey=os.getenv('RASPAP_API_KEY')
10 | #if env not set, set the api key to "insecure"
11 | if apikey == None:
12 | apikey = "insecure"
13 |
14 | print(apikey)
15 | api_key_header = APIKeyHeader(name="access_token", auto_error=False)
16 |
17 | async def get_api_key(api_key_header: str = Security(api_key_header)):
18 | if api_key_header ==apikey:
19 | return api_key_header
20 | else:
21 | raise HTTPException(
22 | status_code=HTTP_403_FORBIDDEN, detail="403: Unauthorized"
23 | )
24 |
25 |
--------------------------------------------------------------------------------
/api/modules/client.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import json
3 |
4 | def get_active_clients_amount(interface):
5 | arp_output = subprocess.run(['arp', '-i', interface], capture_output=True, text=True)
6 | mac_addresses = arp_output.stdout.splitlines()
7 |
8 | if mac_addresses:
9 | grep_pattern = '|'.join(mac_addresses)
10 | output = subprocess.run(['grep', '-iwE', grep_pattern, '/var/lib/misc/dnsmasq.leases'], capture_output=True, text=True)
11 | return len(output.stdout.splitlines())
12 | else:
13 | return 0
14 |
15 | def get_active_clients(interface):
16 | arp_output = subprocess.run(['arp', '-i', interface], capture_output=True, text=True)
17 | arp_mac_addresses = set(line.split()[2] for line in arp_output.stdout.splitlines()[1:])
18 |
19 | dnsmasq_output = subprocess.run(['cat', '/var/lib/misc/dnsmasq.leases'], capture_output=True, text=True)
20 | active_clients = []
21 |
22 | for line in dnsmasq_output.stdout.splitlines():
23 | fields = line.split()
24 | mac_address = fields[1]
25 |
26 | if mac_address in arp_mac_addresses:
27 | client_data = {
28 | "timestamp": int(fields[0]),
29 | "mac_address": fields[1],
30 | "ip_address": fields[2],
31 | "hostname": fields[3],
32 | "client_id": fields[4],
33 | }
34 | active_clients.append(client_data)
35 |
36 | json_output = json.dumps(active_clients, indent=2)
37 | return json_output
38 |
39 |
--------------------------------------------------------------------------------
/api/modules/ddns.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 |
3 | def use():
4 | return subprocess.run("cat /etc/ddclient.conf | grep use= | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
5 |
6 | def method():
7 | #get the contents of the line below "use="
8 | return subprocess.run("awk '/^use=/ {getline; print}' /etc/ddclient.conf | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
9 |
10 | def protocol():
11 | return subprocess.run("cat /etc/ddclient.conf | grep protocol= | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
12 |
13 | def server():
14 | return subprocess.run("cat /etc/ddclient.conf | grep server= | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
15 |
16 | def login():
17 | return subprocess.run("cat /etc/ddclient.conf | grep login= | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
18 |
19 | def password():
20 | return subprocess.run("cat /etc/ddclient.conf | grep password= | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
21 |
22 | def domain():
23 | #get the contents of the line below "password="
24 | return subprocess.run("awk '/^password=/ {getline; print}' /etc/ddclient.conf", shell=True, capture_output=True, text=True).stdout.strip()
--------------------------------------------------------------------------------
/api/modules/dhcp.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import json
3 |
4 | def range_start():
5 | return subprocess.run("cat /etc/dnsmasq.d/090_wlan0.conf |grep dhcp-range= |cut -d'=' -f2| cut -d',' -f1", shell=True, capture_output=True, text=True).stdout.strip()
6 |
7 | def range_end():
8 | return subprocess.run("cat /etc/dnsmasq.d/090_wlan0.conf |grep dhcp-range= |cut -d'=' -f2| cut -d',' -f2", shell=True, capture_output=True, text=True).stdout.strip()
9 |
10 | def range_subnet_mask():
11 | return subprocess.run("cat /etc/dnsmasq.d/090_wlan0.conf |grep dhcp-range= |cut -d'=' -f2| cut -d',' -f3", shell=True, capture_output=True, text=True).stdout.strip()
12 |
13 | def range_lease_time():
14 | return subprocess.run("cat /etc/dnsmasq.d/090_wlan0.conf |grep dhcp-range= |cut -d'=' -f2| cut -d',' -f4", shell=True, capture_output=True, text=True).stdout.strip()
15 |
16 | def range_gateway():
17 | return subprocess.run("cat /etc/dhcpcd.conf | grep routers | cut -d'=' -f2", shell=True, capture_output=True, text=True).stdout.strip()
18 |
19 | def range_nameservers():
20 | output = subprocess.run("cat /etc/dhcpcd.conf", shell=True, capture_output=True, text=True).stdout.strip()
21 |
22 | nameservers = []
23 |
24 | lines = output.split('\n')
25 | for line in lines:
26 | if "static domain_name_server" in line:
27 | servers = line.split('=')[1].strip().split()
28 | nameservers.extend(servers)
29 |
30 | return nameservers
--------------------------------------------------------------------------------
/api/modules/dns.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import json
3 |
4 | def adblockdomains():
5 | output = subprocess.run("cat /etc/raspap/adblock/domains.txt", shell=True, capture_output=True, text=True).stdout.strip()
6 | domains =output.split('\n')
7 | domainlist=[]
8 | for domain in domains:
9 | if domain.startswith('#') or domain=="":
10 | continue
11 | domainlist.append(domain.split('=/')[1])
12 | return domainlist
13 |
14 | def adblockhostnames():
15 | output = subprocess.run("cat /etc/raspap/adblock/hostnames.txt", shell=True, capture_output=True, text=True).stdout.strip()
16 | hostnames = output.split('\n')
17 | hostnamelist=[]
18 | for hostname in hostnames:
19 | if hostname.startswith('#') or hostname=="":
20 | continue
21 | hostnamelist.append(hostname.replace('0.0.0.0 ',''))
22 | return hostnamelist
23 |
24 | def upstream_nameserver():
25 | return subprocess.run("awk '/nameserver/ {print $2}' /run/dnsmasq/resolv.conf", shell=True, capture_output=True, text=True).stdout.strip()
26 |
27 | def dnsmasq_logs():
28 | output = subprocess.run("cat /var/log/dnsmasq.log", shell=True, capture_output=True, text=True).stdout.strip()
29 | log_entries = []
30 | for line in output.split("\n"):
31 | fields = line.split(" ")
32 | log_dict = {
33 | 'timestamp': ' '.join(fields[:3]),
34 | 'process': fields[3][:-1], # Remove the trailing colon
35 | 'message': ' '.join(fields[4:]),
36 | }
37 | log_entries.append(log_dict)
38 | return log_entries
--------------------------------------------------------------------------------
/api/modules/firewall.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 |
3 | def firewall_rules():
4 | return subprocess.run("cat /etc/raspap/networking/firewall/iptables_rules.json", shell=True, capture_output=True, text=True).stdout.strip()
--------------------------------------------------------------------------------
/api/modules/networking.py:
--------------------------------------------------------------------------------
1 | import psutil
2 | import json
3 |
4 | def throughput():
5 | interface_info = {}
6 |
7 | # Get network interfaces
8 | interfaces = psutil.net_if_stats()
9 |
10 | for interface, stats in interfaces.items():
11 | if interface.startswith("lo") or interface.startswith("docker"):
12 | # Skip loopback and docker interface
13 | continue
14 |
15 | try:
16 | # Get network traffic statistics
17 | traffic_stats = psutil.net_io_counters(pernic=True)[interface]
18 | rx_packets = traffic_stats[1]
19 | rx_bytes = traffic_stats[0]
20 | tx_packets = traffic_stats[3]
21 | tx_bytes = traffic_stats[4]
22 |
23 | interface_info[interface] = {
24 | "RX_packets": rx_packets,
25 | "RX_bytes": rx_bytes,
26 | "TX_packets": tx_packets,
27 | "TX_bytes": tx_bytes
28 | }
29 | except KeyError:
30 | # Handle the case where network interface statistics are not available
31 | pass
32 |
33 | return json.dumps(interface_info, indent=2)
34 |
35 | def interfaces():
36 | interface_info = {}
37 |
38 | # Get network interfaces
39 | interfaces = psutil.net_if_addrs()
40 |
41 | for interface, addrs in interfaces.items():
42 | if interface.startswith("lo") or interface.startswith("docker"):
43 | # Skip loopback and docker interface
44 | continue
45 |
46 | ip_address = None
47 | netmask = None
48 | mac_address = None
49 |
50 | for addr in addrs:
51 | if addr.family == 2: # AF_INET corresponds to the integer value 2
52 | # IPv4 address
53 | ip_address = addr.address
54 | netmask = addr.netmask
55 |
56 | # Get MAC address
57 | for addr in psutil.net_if_addrs().get(interface, []):
58 | if addr.family == psutil.AF_LINK:
59 | mac_address = addr.address
60 |
61 | interface_info[interface] = {
62 | "IP_address": ip_address,
63 | "Netmask": netmask,
64 | "MAC_address": mac_address
65 | }
66 | return json.dumps(interface_info, indent=2)
67 |
68 | #TODO: migrate to vnstat, to lose psutil dependency
--------------------------------------------------------------------------------
/api/modules/openvpn.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 |
3 | def client_configs():
4 | return subprocess.run("find /etc/openvpn/client/ -type f | wc -l", shell=True, capture_output=True, text=True).stdout.strip()
5 |
6 | def client_config_names():
7 | config_names_list = []
8 | output = subprocess.run('''ls /etc/openvpn/client/ | grep -v "^client.conf$"''', shell=True, capture_output=True, text=True).stdout.strip()
9 | lines = output.split("\n")
10 | for client in lines:
11 | if "_client" in client:
12 | config_names_dict ={'config':client}
13 | config_names_list.append(config_names_dict)
14 | return config_names_list
15 |
16 | def client_login_names():
17 | config_names_list = []
18 | output = subprocess.run('''ls /etc/openvpn/client/ | grep -v "^client.conf$"''', shell=True, capture_output=True, text=True).stdout.strip()
19 | lines = output.split("\n")
20 | for client in lines:
21 | if "_login" in client:
22 | config_names_dict ={'login':client}
23 | config_names_list.append(config_names_dict)
24 | return config_names_list
25 |
26 | def client_config_active():
27 | output = subprocess.run('''ls -al /etc/openvpn/client/ | grep "client.conf -"''', shell=True, capture_output=True, text=True).stdout.strip()
28 | active_config = output.split("/etc/openvpn/client/")
29 | return(active_config[1])
30 |
31 | def client_login_active():
32 | output = subprocess.run('''ls -al /etc/openvpn/client/ | grep "login.conf -"''', shell=True, capture_output=True, text=True).stdout.strip()
33 | active_config = output.split("/etc/openvpn/client/")
34 | return(active_config[1])
35 |
36 | def client_config_list(client_config):
37 | output = subprocess.run(["cat", f"/etc/openvpn/client/{client_config}"], capture_output=True, text=True).stdout.strip()
38 | return output.split('\n')
39 |
40 | #TODO: where is the logfile??
41 | #TODO: is service connected?
42 |
--------------------------------------------------------------------------------
/api/modules/wireguard.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import re
3 |
4 | def configs():
5 | #ignore symlinks, because wg0.conf is in production the main config, but in insiders it is a symlink
6 | return subprocess.run("find /etc/wireguard/ -type f | wc -l", shell=True, capture_output=True, text=True).stdout.strip()
7 |
8 | def client_config_names():
9 | config_names_list = []
10 | output = subprocess.run('''ls /etc/wireguard/ | grep -v "^wg0.conf$"''', shell=True, capture_output=True, text=True).stdout.strip()
11 | lines = output.split("\n")
12 | for client in lines:
13 | config_names_dict ={'config':client}
14 | config_names_list.append(config_names_dict)
15 | return config_names_list
16 |
17 | def client_config_active():
18 | output = subprocess.run('''ls -al /etc/wireguard/ | grep "wg0.conf -"''', shell=True, capture_output=True, text=True).stdout.strip()
19 | active_config = output.split("/etc/wireguard/")
20 | return(active_config[1])
21 |
22 | #TODO: where is the logfile??
23 | #TODO: is service connected?
24 |
--------------------------------------------------------------------------------
/api/requirements.txt:
--------------------------------------------------------------------------------
1 | fastapi==0.109.1
2 | uvicorn==0.25.0
3 | psutil==5.9.8
4 | python-dotenv==1.0.1
5 |
6 |
--------------------------------------------------------------------------------
/app/css/dark.css:
--------------------------------------------------------------------------------
1 | /*
2 | Theme Name: Lights Out
3 | Author: @billz
4 | Author URI: https://github.com/billz
5 | Description: A Bootstrap dark mode theme for RaspAP
6 | License: GNU General Public License v3.0
7 | */
8 |
9 | @import url('custom.php');
10 |
11 | html[data-bs-theme="dark"] {
12 | background-color: var(--bs-dark);
13 | color: var(--bs-light);
14 | }
15 |
16 | html[data-bs-theme="dark"] body,
17 | html[data-bs-theme="dark"] footer,
18 | html[data-bs-theme="dark"] .sb-sidenav,
19 | html[data-bs-theme="dark"] .sb-topnav,
20 | html[data-bs-theme="dark"] .card,
21 | html[data-bs-theme="dark"] .card-footer {
22 | background-color: var(--bs-dark);
23 | }
24 |
25 | html[data-bs-theme="dark"] .card-body,
26 | html[data-bs-theme="dark"] .card-footer,
27 | html[data-bs-theme="dark"] .info-item-xs,
28 | html[data-bs-theme="dark"] .table>:not(caption)>*>* {
29 | color: var(--bs-secondary);
30 | }
31 |
32 | html[data-bs-theme="dark"] .sb-topnav.navbar {
33 | background-color: var(--bs-dark) !important;
34 | color: var(--bs-light);
35 | }
36 |
37 | html[data-bs-theme="dark"] .sb-topnav.navbar,
38 | html[data-bs-theme="dark"] .sb-topnav.navbar a {
39 | color: var(--raspap-theme-color) !important;
40 | }
41 |
42 | html[data-bs-theme="dark"] .sb-topnav.navbar a:hover,
43 | html[data-bs-theme="dark"] .sb-topnav.navbar a:focus {
44 | color: var(--raspap-theme-darker) !important;
45 | }
46 |
47 | html[data-bs-theme="dark"] .sb-topnav.navbar {
48 | --bs-navbar-bg: var(--bs-dark);
49 | }
50 |
51 | html[data-bs-theme="dark"] .sb-topnav.navbar.navbar-light {
52 | color: var(--bs-light);
53 | }
54 |
55 | html[data-bs-theme="dark"] .card {
56 | border-color: var(--bs-secondary);
57 | color: var(--bs-light);
58 | }
59 |
60 | html[data-bs-theme="dark"] .card-footer {
61 | border-color: var(--bs-secondary);
62 | }
63 |
64 | html[data-bs-theme="dark"] .nav-tabs {
65 | --bs-nav-tabs-link-active-color: var(--bs-light);
66 | --bs-nav-tabs-link-active-bg: var(--bs-dark);
67 | --bs-nav-tabs-link-active-border-color: var(--bs-secondary) var(--bs-secondary) var(--bs-dark);
68 | --bs-nav-tabs-border-color: var(--bs-secondary);
69 | --bs-nav-tabs-link-hover-border-color: var(--bs-secondary);
70 | }
71 |
72 | html[data-bs-theme="dark"] .btn {
73 | color: var(--bs-gray-800);
74 | opacity: 75%;
75 | }
76 |
77 | html[data-bs-theme="dark"] select,
78 | html[data-bs-theme="dark"] .form-control {
79 | background-color: var(--bs-dark);
80 | border-color: var(--bs-secondary);
81 | color: var(--bs-light);
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/app/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/app/icons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/icons/favicon-96x96.png
--------------------------------------------------------------------------------
/app/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/icons/favicon.ico
--------------------------------------------------------------------------------
/app/icons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RaspAP Admin Panel",
3 | "short_name": "RaspAP",
4 | "icons": [
5 | {
6 | "src": "/app/icons/web-app-manifest-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png",
9 | "purpose": "maskable"
10 | },
11 | {
12 | "src": "/app/icons/web-app-manifest-512x512.png",
13 | "sizes": "512x512",
14 | "type": "image/png",
15 | "purpose": "maskable"
16 | }
17 | ],
18 | "theme_color": "#ffffff",
19 | "background_color": "#ffffff",
20 | "display": "standalone"
21 | }
22 |
--------------------------------------------------------------------------------
/app/icons/web-app-manifest-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/icons/web-app-manifest-192x192.png
--------------------------------------------------------------------------------
/app/icons/web-app-manifest-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/icons/web-app-manifest-512x512.png
--------------------------------------------------------------------------------
/app/img/dashed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/img/insiders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/img/insiders.png
--------------------------------------------------------------------------------
/app/img/raspAP-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/app/img/raspAP-logo.png
--------------------------------------------------------------------------------
/app/img/right-dashed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/img/right-solid.php:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
23 |
24 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/img/solid.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | 0.75,
20 | 'out' => 297.75,
21 | 'device-2' => 198.75,
22 | 'device-3' => 397.058,
23 | 'device-4' => 595.211
24 | ];
25 |
26 | // Calculate joint line segments
27 | if ($showJoint) {
28 | $activeDevices = array_filter([$showDevice1, $showDevice2, $showDevice3, $showDevice4]);
29 | $activeYs = [];
30 |
31 | foreach ($devicePositions as $device => $y) {
32 | if (isset($_GET[$device])) {
33 | $activeYs[] = $y;
34 | }
35 | }
36 |
37 | // Add top/bottom if first/last device is connected
38 | if ($showDevice1) array_unshift($activeYs, 0);
39 | if ($showDevice4) $activeYs[] = 596;
40 |
41 | // Draw segments between consecutive points
42 | for ($i = 1; $i < count($activeYs); $i++) {
43 | $y1 = $activeYs[$i-1];
44 | $y2 = $activeYs[$i];
45 | echo " ";
46 | }
47 | }
48 | ?>
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/img/uri-qr-code.php:
--------------------------------------------------------------------------------
1 | date rx tx
')}("divTableBandwidth"+e,e);r.ajax({url:a,dataType:"json",beforeSend:function(){r("#divLoaderBandwidth"+e).removeClass("hidden")}}).done(function(t){r("#divLoaderBandwidth"+e).addClass("hidden"),n.setData(t),r("#tableBandwidth"+e).DataTable({searching:!1,paging:!1,data:t,order:[[0,"ASC"]],columns:[{data:"date"},{data:"rx",title:i.receive+" "+d.toUpperCase()},{data:"tx",title:i.send+" "+d.toUpperCase()}]})}).fail(function(t,e){window.console?console.error("server error"):alert("server error")})}r(document).ready(function(){r('#tabbarBandwidth a[data-toggle="tab"]').on("shown.bs.tab",t),r("#cbxInterfacehourly").on("change",t),r("#cbxInterfacedaily").on("change",t),r("#cbxInterfacemonthly").on("change",t),t()})}(jQuery,t);
--------------------------------------------------------------------------------
/app/js/huebee.js:
--------------------------------------------------------------------------------
1 | // Initialize Huebee color picker
2 | var elem = document.querySelector('.color-input');
3 | var hueb = new Huebee( elem, {
4 | notation: 'hex',
5 | saturations: 2,
6 | customColors: [ '#d8224c', '#dd4814', '#ea0', '#19f', '#333' ],
7 | className: 'light-picker',
8 | hue0: 210
9 | });
10 |
11 | // Set custom color if defined
12 | var color = getCookie('color');
13 | if (color == null || color == '') {
14 | color = '#2b8080';
15 | }
16 | hueb.setColor(color);
17 |
18 | // Change event
19 | hueb.on( 'change', function( color, hue, sat, lum ) {
20 | setCookie('color',color,90);
21 | })
22 |
23 |
--------------------------------------------------------------------------------
/app/js/linkquality.js:
--------------------------------------------------------------------------------
1 | // Link quality gauge for ChartJS
2 |
3 | // Support for dark theme
4 | theme = getCookie('theme');
5 | if (theme == 'lightsout.css') {
6 | var borderColor = 'rgba(37, 153, 63, 1)';
7 | var labelColor = 'rgba(37, 153, 63, 1)';
8 | } else if (theme == 'material-light.php') {
9 | var borderColor = '#f2f2fb';
10 | var labelColor = '#f2f2fb';
11 | } else if (theme == 'material-dark.php') {
12 | var borderColor = '#f2f2fb';
13 | var labelColor = '#f2f2fb';
14 | } else {
15 | var borderColor = 'rgba(147, 210, 162, 1)';
16 | var labelColor = 'rgba(130, 130, 130, 1)';
17 | }
18 |
19 | let data1 = {
20 | datasets: [{
21 | data: [linkQ, 100-linkQ],
22 | backgroundColor: 'transparent',
23 | borderColor: borderColor,
24 | }],
25 | };
26 |
27 | let config = {
28 | type: 'doughnut',
29 | data: data1,
30 | options: {
31 | aspectRatio: 2,
32 | responsive: true,
33 | maintainAspectRatio: false,
34 | tooltips: {enabled: false},
35 | hover: {mode: null},
36 | legend: {
37 | display: false,
38 | },
39 | rotation: (2/3)*Math.PI,//2+(1/3),
40 | circumference: (1+(2/3)) * Math.PI, // * Math.PI,
41 | cutoutPercentage: 80,
42 | animation: {
43 | animateScale: false,
44 | animateRotate: true
45 | },
46 | tooltips: {
47 | enabled: false
48 | }
49 | },
50 | centerText: {
51 | display: true,
52 | text: linkQ + "%"
53 | },
54 | plugins: [{
55 | beforeDraw: function(chart) {
56 | if (chart.config.centerText.display !== null &&
57 | typeof chart.config.centerText.display !== 'undefined' &&
58 | chart.config.centerText.display) {
59 | drawLinkQ(chart);
60 | }
61 | }
62 | }]
63 | };
64 |
65 | function drawLinkQ(chart) {
66 |
67 | let width = chart.chart.width;
68 | let height = chart.chart.height;
69 | let ctx = chart.chart.ctx;
70 |
71 | ctx.restore();
72 | let fontSize = (height / 100).toFixed(2);
73 | ctx.font = fontSize + "em sans-serif";
74 | ctx.fillStyle = labelColor;
75 | ctx.textBaseline = "middle";
76 |
77 | let text = chart.config.centerText.text;
78 | let textX = Math.round((width - ctx.measureText(text).width) * 0.5);
79 | let textY = height / 2;
80 | ctx.fillText(text, textX, textY);
81 | ctx.save();
82 | }
83 |
84 | window.onload = function() {
85 | let ctx = document.getElementById("divChartLinkQ").getContext("2d");
86 | var chart = new Chart(ctx, config);
87 | };
88 |
89 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "raspap/raspap-webgui",
3 | "description": "Simple wireless AP setup and mangement for Debian-based devices",
4 | "license": "GPL-3.0",
5 | "homepage": "https://raspap.com/",
6 | "keywords": ["raspberrypi", "debian", "armbian", "wifi"],
7 | "type": "raspap-core",
8 | "authors": [
9 | {
10 | "name": "RaspAP Team",
11 | "email": "billzimmerman@gmail.com",
12 | "homepage": "https://raspap.com/"
13 | }
14 | ],
15 | "require": {
16 | "php": "^8.2",
17 | "phpoption/phpoption": "^1.9",
18 | "ext-mbstring": "*"
19 | },
20 | "require-dev": {
21 | "php-parallel-lint/php-parallel-lint": "^1.2.0",
22 | "phpcompatibility/php-compatibility": "^9.3.5",
23 | "squizlabs/php_codesniffer": "^3.9.0",
24 | "ext-simplexml": "*"
25 | },
26 | "scripts": {
27 | "lint": "parallel-lint . --exclude vendor",
28 | "phpcs": "phpcs -p -s --config-set installed_paths vendor/phpcompatibility/php-compatibility .",
29 | "test": [
30 | "composer lint",
31 | "composer phpcs"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/config/090_raspap.conf:
--------------------------------------------------------------------------------
1 | # RaspAP default config
2 | log-facility=/var/log/dnsmasq.log
3 | conf-dir=/etc/dnsmasq.d
4 |
5 |
--------------------------------------------------------------------------------
/config/090_wlan0.conf:
--------------------------------------------------------------------------------
1 | # RaspAP wlan0 configuration for wired (ethernet) AP mode
2 | interface=wlan0
3 | domain-needed
4 | dhcp-range=10.3.141.50,10.3.141.254,255.255.255.0,12h
5 | dhcp-option=6,9.9.9.9,1.1.1.1
6 |
7 |
--------------------------------------------------------------------------------
/config/50-raspap-router.conf:
--------------------------------------------------------------------------------
1 | server.modules += (
2 | "mod_rewrite",
3 | )
4 |
5 | $HTTP["url"] =~ "^/REPLACE_ME/(?!(dist|app|ajax|config)).*" {
6 | url.rewrite-once = ( "^/REPLACE_ME/(.*?)(\?.+)?$"=>"/REPLACE_ME/index.php/$1$2" )
7 | server.error-handler-404 = "/REPLACE_ME/index.php"
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/config/blocklists.json:
--------------------------------------------------------------------------------
1 | {
2 | "StevenBlack/hosts": [
3 | "StevenBlack/hosts (default)"
4 | ],
5 | "badmojr/hosts": [
6 | "badmojr/1Hosts (Mini)",
7 | "badmojr/1Hosts (Lite)",
8 | "badmojr/1Hosts (Pro)",
9 | "badmojr/1Hosts (Xtra)"
10 | ],
11 | "OISD/domains": [
12 | "oisd/big (default)",
13 | "oisd/small",
14 | "oisd/nsfw"
15 | ]
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/config/client_config/70-mobile-data-sticks.rules:
--------------------------------------------------------------------------------
1 | # mobile data modem - ttyUSB0 device appears
2 | SUBSYSTEM=="tty", KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_ppp0_device.service"
3 |
4 |
5 |
--------------------------------------------------------------------------------
/config/client_config/80-raspap-net-devices.rules:
--------------------------------------------------------------------------------
1 | SUBSYSTEM=="net", ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="14db", NAME="hilink%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="start start_huawei_hilink@hilink%n.service"
2 |
3 |
4 |
--------------------------------------------------------------------------------
/config/client_config/info_huawei_modem.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Information about HUAWEI modem - via AT commands
3 | # ------------------------------------------------
4 | # get info about the device and signal
5 | # parameter: $1 - see opts list below
6 | # $2 - tty device name for the communicaton (optional)
7 | # returns the value of the parameter, or "none" if not found or empty
8 | #
9 | # requires: socat
10 | #
11 | # zbchristian 2020
12 |
13 | opts=("manufacturer" "device" "imei" "imsi" "telnumber" "mode" "signal" "operator")
14 |
15 | # at command to extract information
16 | atcmds=("AT+CGMI" "AT+CGMM" "AT+CGSN" "AT+CIMI" "AT+CNUM" "AT+COPS?" "AT+CSQ" "AT+COPS?")
17 | # regexp pattern to extract wanted information from result string
18 | pats=( " " " " " " " " ".*\,\"([0-9\+]*)\".*" '.*\,([0-9])$' ".*: ([0-9]*).*" '.*\,\"([^ ]*)\".*$')
19 |
20 | # tty device for communication - usually 3 tty devices are created and the 3rd ttyUSB2 is available, even, when the device is connected
21 | dev="/dev/ttyUSB2"
22 |
23 | atsilent="AT^CURC=0"
24 |
25 | if [ ! -z $2 ]; then dev=$2; fi
26 |
27 | idx=-1
28 | opt=${opts[0]}
29 | if [ ! -z $1 ]; then opt=$1; fi
30 |
31 | for i in "${!opts[@]}"; do
32 | if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi
33 | done
34 | if [[ $idx == -1 ]];then echo "none"; exit; fi
35 |
36 | atcmd=${atcmds[$idx]}
37 | pat=${pats[$idx]}
38 |
39 |
40 | result=`(echo $atsilent; echo $atcmd) | sudo /usr/bin/socat - $dev`
41 | # escape the AT command to be used in the regexp
42 | atesc=${atcmd//[\+]/\\+}
43 | atesc=${atesc//[\?]/\\?}
44 | result=`echo $result | sed -rn 's/.*'"$atesc"'\s([^ ]+|[^ ]+ [^ ]+)\sOK.*$/\1/pg'`
45 | if [[ $pat != " " ]]; then
46 | result=`echo $result | sed -rn 's/'"$pat"'/\1/pg'`
47 | fi
48 |
49 | if [ -z "$result" ]; then result="none"; fi
50 |
51 | echo $result
52 |
53 |
--------------------------------------------------------------------------------
/config/client_config/interfaces:
--------------------------------------------------------------------------------
1 | # interfaces(5) file used by ifup(8) and ifdown(8)
2 |
3 | # Please note that this file is written to be used with dhcpcd
4 | # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
5 |
6 | # Include files from /etc/network/interfaces.d:
7 | source-directory /etc/network/interfaces.d
8 |
9 | auto ppp0
10 | iface ppp0 inet wvdial
11 | provider connect
12 | pre-up /usr/local/sbin/ppp0_setpin.sh
13 | up /usr/local/sbin/ppp0_route.sh
14 |
--------------------------------------------------------------------------------
/config/client_config/onoff_huawei_hilink.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # connect/disconnect Huawei mobile data stick in Hilink mode (e.g. E3372h)
3 | # ========================================================================
4 | #
5 | # options: -u, --user - user name (default "admin")
6 | # -P, --password - password
7 | # -h, --host - host ip address (default 192.168.8.1)
8 | # -d, --devname - device name (IP is extracted using default route)
9 | # -p, --pin - PIN of SIM card
10 | # -c, --connect - connect 0/1 to set datamode off/on
11 | #
12 | # required software: curl, base64, sha256sum
13 | #
14 | # zbchristian 2021
15 |
16 | # include the hilink API (defaults: hilink_user=admin, hilink_host=192.168.8.1)
17 | source /usr/local/sbin/huawei_hilink_api.sh
18 |
19 | # include the raspap helper functions
20 | source /usr/local/sbin/raspap_helpers.sh
21 |
22 | datamode=""
23 | devname=""
24 | while [ -n "$1" ]; do
25 | case "$1" in
26 | -u|--user) hilink_user="$2"; shift ;;
27 | -P|--password) hilink_password="$2"; shift ;;
28 | -p|--pin) if [[ $2 =~ ^[0-9]{4,8} ]]; then hilink_pin="$2"; fi; shift ;;
29 | -h|--host) hilink_host="$2"; shift ;;
30 | -d|--devname) devname="$2"; shift ;;
31 | -c|--connect) if [ "$2" = "1" ]; then datamode=1; else datamode=0; fi; shift ;;
32 | esac
33 | shift
34 | done
35 |
36 | if [ ! -z "$devname" ]; then # get host IP for given device name
37 | gw=$(ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev $devname.*/\1/p")
38 | if [ -z "$gw" ]; then exit; fi # device name not found in routing list -> abort
39 | hilink_host="$gw"
40 | fi
41 |
42 | if [ -z "$hilink_password" ] || [ -z "$hilink_pin" ]; then
43 | _getAuthRouter
44 | if [ ! -z "$raspap_user" ]; then hilink_user="$raspap_user"; fi
45 | if [ ! -z "$raspap_password" ]; then hilink_password="$raspap_password"; fi
46 | if [ ! -z "$raspap_pin" ]; then hilink_pin="$raspap_pin"; fi
47 | fi
48 |
49 | echo "Hilink: switch device at $hilink_host to mode $datamode" | systemd-cat
50 |
51 | status="usage: -c 1/0 to disconnect/connect"
52 | if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi
53 |
54 | if ! _switchMobileData "$datamode"; then echo -n "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi
55 |
56 | if ! _closeHilinkAPI; then echo -n "Hilink: failed - return status: $status . Error: ";_getErrorText; fi
57 |
58 |
59 |
--------------------------------------------------------------------------------
/config/client_config/ppp0_route.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # get gateway and ip address of UTMS modem connected to ppp0
4 | # add a default route
5 | # called by /etc/network/interfaces.d/ppp0, when device is coming up
6 | #
7 | ppp0rt=""
8 | let i=1
9 | while [ -z "$ppp0rt" ] ; do
10 | let i+=1
11 | if [ $i -gt 20 ]; then
12 | exit 1
13 | fi
14 | sleep 1
15 | ppp0rt=`ip route list | grep -m 1 ppp0`
16 | done
17 | gate=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\1/p'`
18 | src=`echo $ppp0rt | sed -rn 's/(([0-9]{1,3}\.){3}[0-9]{1,3}).*ppp0.*src (([0-9]{1,3}\.){3}[0-9]{1,3})/\3/p'`
19 |
20 | ip route add default via $gate proto dhcp src $src metric 10
21 | exit 0
22 |
--------------------------------------------------------------------------------
/config/client_config/ppp0_setpin.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # in case /dev/ttyUSB0 does not exist, wait for it at most 30 seconds
3 | let i=1
4 | while ! test -c /dev/ttyUSB0; do
5 | let i+=1
6 | if [ $i -gt 2 ]; then
7 | logger -s -t setpin "/dev/ttyUSB0 does not exist"
8 | exit 3
9 | fi
10 | logger -s -t setpin "waiting 3 seconds for /dev/ttyUSB0"
11 | sleep 3
12 | done
13 | # check for pin and set it if necessary
14 | wvdial pinstatus 2>&1 | grep -q '^+CPIN: READY'
15 | if [ $? -eq 0 ]; then
16 | logger -s -t setpin "SIM card is ready to use :-)"
17 | else
18 | logger -s -t setpin "setting PIN"
19 | wvdial pin 2>/dev/null
20 | fi
21 | exit 0
22 |
--------------------------------------------------------------------------------
/config/client_config/raspap_helpers.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Helper functions to extract informations from RaspAP config/settings
4 | #
5 | # zbchristian 2021
6 | #
7 | # get the values of a RaspAP config variable
8 | # call: _getRaspapConfig RASPAP_MOBILEDATA_CONFIG
9 |
10 | raspap_webroot="/var/www/html"
11 |
12 | function _getWebRoot() {
13 | local path
14 | path=$(cat /etc/lighttpd/lighttpd.conf | sed -rn "s/server.document-root \s*= \"([^ \s]*)\"/\1/p")
15 | if [ ! -z "$path" ]; then raspap_webroot="$path"; fi
16 | if [ -z "$path" ]; then return 1; else return 0; fi
17 | }
18 |
19 | # expand an RaspAP config variable utilizing PHP
20 | function _getRaspapConfig() {
21 | local conf var
22 | raspap_config=""
23 | var="$1"
24 | if [ ! -z "$var" ]; then
25 | if ! _getWebRoot; then return 1; fi
26 | conf="$raspap_webroot/includes/config.php"
27 | if [ -f "$conf" ]; then
28 | conf=$(php -r 'include "'$conf'"; echo '$var';' 2> /dev/null)
29 | if [ ! -z "$conf" ] && [ -d ${conf%/*} ]; then raspap_config="$conf"; fi
30 | fi
31 | fi
32 | if [ -z "$raspap_config" ]; then return 1; else return 0; fi
33 | }
34 |
35 | # Username and password for mobile data devices is stored in a file (RASPAP_MOBILEDATA_CONFIG)
36 | function _getAuthRouter() {
37 | local mfile mdata pin user pw
38 | if ! _getRaspapConfig "RASPI_MOBILEDATA_CONFIG"; then return 1; fi
39 | mfile="$raspap_config"
40 | if [ -f $mfile ]; then
41 | mdata=$(cat "$mfile")
42 | pin=$(echo "$mdata" | sed -rn 's/pin = ([^ \s]*)/\1/ip')
43 | if [ ! -z "$pin" ]; then raspap_pin="$pin"; fi
44 | user=$(echo "$mdata" | sed -rn 's/router_user = ([^ \s]*)/\1/ip')
45 | if [ ! -z "$user" ]; then raspap_user="$user"; fi
46 | pw=$(echo "$mdata" | sed -rn 's/router_pw = ([^ \s]*)/\1/ip')
47 | if [ ! -z "$pw" ]; then raspap_password="$pw"; fi
48 | return 0
49 | fi
50 | return 1
51 | }
52 |
--------------------------------------------------------------------------------
/config/client_config/start_huawei_hilink@.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Bring up HUAWEI mobile hilink device
3 |
4 | [Service]
5 | Type=oneshot
6 | RemainAfterExit=no
7 | ExecStart=/bin/sleep 15
8 | ExecStart=/usr/local/sbin/onoff_huawei_hilink.sh -c 1 -d %i
9 |
10 | [Install]
11 | Alias=start_ltemodem.service
12 | WantedBy=multi-user.target
13 |
14 |
--------------------------------------------------------------------------------
/config/client_config/start_ppp0_device.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Start ppp0 interface
3 | BindsTo=dev-ttyUSB0.device
4 | After=dev-ttyUSB0.device
5 |
6 | [Service]
7 | Type=forking
8 | RemainAfterExit=yes
9 | ExecStart=/sbin/ifup ppp0
10 | ExecStop=/sbin/ifdown ppp0
11 |
12 | [Install]
13 | Alias=startppp0.service
14 | WantedBy=multi-user.target
15 |
16 |
17 |
--------------------------------------------------------------------------------
/config/client_config/wvdial.conf:
--------------------------------------------------------------------------------
1 | [Dialer Defaults]
2 | Modem Type = Analog Modem
3 | ISDN = 0
4 | Baud = 9600
5 | Modem = /dev/ttyUSB0
6 |
7 | [Dialer pin]
8 | Init1 = AT+CPIN="XXXX"
9 |
10 | [Dialer connect]
11 | Init1 = ATZ
12 | Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
13 | Init3 = AT+CGDCONT=1,"IP","web.vodafone.de"
14 | New PPPD = yes
15 | Phone = *99#
16 | Password = me
17 | Username = vodafone
18 | Stupid Mode = 1
19 |
20 | [Dialer pinstatus]
21 | Init1 = AT+CPIN?
22 |
--------------------------------------------------------------------------------
/config/defaults.json:
--------------------------------------------------------------------------------
1 | {
2 | "dhcp": {
3 | "wlan0": {
4 | "static ip_address": [ "10.3.141.1/24" ],
5 | "static routers": [ "10.3.141.1" ],
6 | "static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
7 | "subnetmask": [ "255.255.255.0" ]
8 | },
9 | "wlan1": {
10 | "static ip_address": [ "10.9.141.1/24" ],
11 | "static routers": [ "10.9.141.1" ],
12 | "static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
13 | "subnetmask": [ "255.255.255.0" ]
14 | },
15 | "uap0": {
16 | "static ip_address": [ "192.168.50.1/24" ],
17 | "static routers": [ "192.168.50.1" ],
18 | "static domain_name_server": [ "1.1.1.1 8.8.8.8" ],
19 | "subnetmask": [ "255.255.255.0" ]
20 | },
21 | "options": {
22 | "# RaspAP default configuration": null,
23 | "hostname": null,
24 | "clientid": null,
25 | "persistent": null,
26 | "option rapid_commit": null,
27 | "option domain_name_servers, domain_name, domain_search, host_name": null,
28 | "option classless_static_routes": null,
29 | "option ntp_servers": null,
30 | "require dhcp_server_identifier": null,
31 | "slaac private": null,
32 | "nohook lookup-hostname": null
33 | }
34 | },
35 | "dnsmasq": {
36 | "wlan0": {
37 | "dhcp-range": [ "10.3.141.50,10.3.141.254,255.255.255.0,12h" ]
38 | },
39 | "wlan1": {
40 | "dhcp-range": [ "10.9.141.50,10.9.141.254,255.255.255.0,12h" ]
41 | },
42 | "uap0": {
43 | "dhcp-range": [ "192.168.50.50,192.168.50.150,12h" ]
44 | }
45 | },
46 | "wireguard": {
47 | "server": {
48 | "Address": [ "10.8.2.1/24" ],
49 | "ListenPort": [ "51820" ],
50 | "DNS": [ "9.9.9.9" ],
51 | "PostUp": [ "iptables -A FORWARD -i wlan0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE" ],
52 | "PostDown": [ "iptables -D FORWARD -i wlan0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE" ]
53 | },
54 | "peer": {
55 | "Address": [ "10.8.1.2/24" ],
56 | "Endpoint": [ "10.8.2.1:51820" ],
57 | "ListenPort": [ "21841" ],
58 | "AllowedIPs": ["10.8.2.0/24"],
59 | "PersistentKeepalive": [ "15" ]
60 | }
61 | },
62 | "txpower": {
63 | "dbm": [ "auto", "30", "20", "17", "10", "6", "3", "1", "0" ]
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/config/dhcpcd.conf:
--------------------------------------------------------------------------------
1 | # RaspAP default configuration
2 | hostname
3 | clientid
4 | persistent
5 | option rapid_commit
6 | option domain_name_servers, domain_name, domain_search, host_name
7 | option classless_static_routes
8 | option ntp_servers
9 | require dhcp_server_identifier
10 | slaac private
11 | nohook lookup-hostname
12 |
13 | # RaspAP wlan0 configuration
14 | interface wlan0
15 | static ip_address=10.3.141.1/24
16 | static routers=10.3.141.1
17 | static domain_name_server=9.9.9.9 1.1.1.1
18 | nogateway
19 |
20 |
--------------------------------------------------------------------------------
/config/dns-servers.json:
--------------------------------------------------------------------------------
1 | {
2 | "Cloudflare": [
3 | "1.0.0.1",
4 | "1.1.1.1"
5 | ],
6 | "Freenom World": [
7 | "80.80.80.80",
8 | "80.80.81.81"
9 | ],
10 | "German Privacy Foundation": [
11 | "62.141.58.13",
12 | "85.25.251.254",
13 | "87.118.100.175",
14 | "94.75.228.29"
15 | ],
16 | "Google": [
17 | "8.8.4.4",
18 | "8.8.8.8"
19 | ],
20 | "OpenDNS": [
21 | "208.67.220.220",
22 | "208.67.222.222"
23 | ],
24 | "Quad9": [
25 | "9.9.9.9",
26 | "149.112.112.112"
27 | ],
28 | "Yandex.DNS": [
29 | "77.88.8.2",
30 | "77.88.8.88"
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/config/hostapd.conf:
--------------------------------------------------------------------------------
1 | driver=nl80211
2 | ctrl_interface=/var/run/hostapd
3 | ctrl_interface_group=0
4 | beacon_int=100
5 | auth_algs=1
6 | wpa_key_mgmt=WPA-PSK
7 | ssid=RaspAP
8 | channel=1
9 | hw_mode=g
10 | wpa_passphrase=ChangeMe
11 | interface=wlan0
12 | wpa=2
13 | wpa_pairwise=CCMP
14 | country_code=GB
15 | ## Rapberry Pi 3 specific to on board WLAN/WiFi
16 | #ieee80211n=1 # 802.11n support (Raspberry Pi 3)
17 | #wmm_enabled=1 # QoS support (Raspberry Pi 3)
18 | #ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] # (Raspberry Pi 3)
19 |
20 | ## RaspAP wireless client AP mode
21 | #interface=uap0
22 |
23 | ## RaspAP bridge AP mode, disabled by default
24 | #bridge=br0
25 |
--------------------------------------------------------------------------------
/config/raspap-br0-member-eth0.network:
--------------------------------------------------------------------------------
1 | [Match]
2 | Name=eth0
3 |
4 | [Network]
5 | Bridge=br0
6 |
--------------------------------------------------------------------------------
/config/raspap-bridge-br0.netdev:
--------------------------------------------------------------------------------
1 | [NetDev]
2 | Name=br0
3 | Kind=bridge
4 |
--------------------------------------------------------------------------------
/config/raspap-bridge-br0.netplan:
--------------------------------------------------------------------------------
1 | network:
2 | version: 2
3 | renderer: networkd
4 | ethernets:
5 | eth0:
6 | dhcp4: no
7 | bridges:
8 | br0:
9 | dhcp4: yes
10 | interfaces:
11 | - eth0
12 |
--------------------------------------------------------------------------------
/config/vpn-providers.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": [
3 | {
4 | "id": 1,
5 | "name": "ExpressVPN",
6 | "bin_path": "/usr/bin/expressvpn",
7 | "install_page": "https://www.expressvpn.com/support/vpn-setup/app-for-linux/",
8 | "account_page": "https://www.expressvpn.com/subscriptions",
9 | "cmd_overrides": {
10 | "countries": "list all",
11 | "log": "diagnostics",
12 | "version": "-v"
13 | },
14 | "regex": {
15 | "status": "\/not connected\/",
16 | "pattern": "\/^(.{2,5})\\s(?:.{1,28})(.{1,26}).*$\/",
17 | "replace": "$1,$2",
18 | "slice": 3
19 | }
20 | },
21 | {
22 | "id": 2,
23 | "name": "Mullvad VPN",
24 | "bin_path": "/usr/bin/mullvad",
25 | "install_page": "https://mullvad.net/en/download/vpn/linux",
26 | "account_page": "https://mullvad.net/en/account",
27 | "cmd_overrides": {
28 | "account": "account get",
29 | "countries": "relay list",
30 | "log": "status -v",
31 | "version": "--version"
32 | },
33 | "regex": {
34 | "status": "\/disconnected\/",
35 | "pattern": "\/^(.*),.*$\/",
36 | "replace": "$1"
37 | }
38 | },
39 | {
40 | "id": 3,
41 | "name": "NordVPN",
42 | "bin_path": "/usr/bin/nordvpn",
43 | "install_page": "https://nordvpn.com/download/linux/",
44 | "account_page": "https://my.nordaccount.com/dashboard/",
45 | "cmd_overrides": {
46 | "log": "status"
47 | },
48 | "regex": {
49 | "status": "\/status: disconnected\/",
50 | "pattern": "(\\w+)\\s+",
51 | "replace": "$1,$1\\n"
52 | }
53 | },
54 | {
55 | "id": 4,
56 | "name": "AdGuard VPN",
57 | "bin_path": "/usr/local/bin/adguardvpn-cli",
58 | "install_page": "https://adguard-vpn.com/kb/adguard-vpn-for-linux/installation/",
59 | "account_page": "https://my.adguard-vpn.com/en/account/product/vpn",
60 | "cmd_overrides": {
61 | "countries": "list-locations",
62 | "connect": "connect -y -l",
63 | "log": "status",
64 | "account": "license",
65 | "version": "--version"
66 | },
67 | "regex": {
68 | "status": "\/vpn is disconnected\/",
69 | "pattern": "/^([A-Z]{2})\\s+.*?\\s([A-Za-z]+(?:\\s[A-Za-z]+)?)\\s+\\d+$/m",
70 | "replace": "$2",
71 | "slice": 3
72 | }
73 | }
74 | ]
75 | }
76 |
--------------------------------------------------------------------------------
/crowdin.yml:
--------------------------------------------------------------------------------
1 | files:
2 | - source: /locale/en_US/LC_MESSAGES/messages.po
3 | translation: /locale/%locale_with_underscore%/LC_MESSAGES/%original_file_name%
4 |
--------------------------------------------------------------------------------
/dist/datatables/dataTables.bootstrap4.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | DataTables Bootstrap 4 integration
3 | ©2011-2017 SpryMedia Ltd - datatables.net/license
4 | */
5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
6 | renderer:"bootstrap"});b.extend(f.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap4",sFilterInput:"form-control form-control-sm",sLengthSelect:"custom-select custom-select-sm form-control form-control-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();
7 | !b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};l=0;for(h=f.length;l",
8 | {"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#","aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex,"class":"page-link"}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('').children("ul"),s);i!==m&&b(h).find("[data-dt-idx="+i+"]").focus()};return f});
9 |
--------------------------------------------------------------------------------
/dist/font-awesome/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Font Awesome Free License
2 | -------------------------
3 |
4 | Font Awesome Free is free, open source, and GPL friendly. You can use it for
5 | commercial projects, open source projects, or really almost whatever you want.
6 | Full Font Awesome Free license: https://fontawesome.com/license/free.
7 |
8 | # Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
9 | In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
10 | packaged as SVG and JS file types.
11 |
12 | # Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)
13 | In the Font Awesome Free download, the SIL OFL license applies to all icons
14 | packaged as web and desktop font files.
15 |
16 | # Code: MIT License (https://opensource.org/licenses/MIT)
17 | In the Font Awesome Free download, the MIT license applies to all non-font and
18 | non-icon files.
19 |
20 | # Attribution
21 | Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
22 | Awesome Free files already contain embedded comments with sufficient
23 | attribution, so you shouldn't need to do anything additional when using these
24 | files normally.
25 |
26 | We've kept attribution comments terse, so we ask that you do not actively work
27 | to remove them from files, especially code. They're a great way for folks to
28 | learn about Font Awesome.
29 |
30 | # Brand Icons
31 | All brand icons are trademarks of their respective owners. The use of these
32 | trademarks does not indicate endorsement of the trademark holder by Font
33 | Awesome, nor vice versa. **Please do not use brand logos for any purpose except
34 | to represent the company, product, or service to which they refer.**
35 |
--------------------------------------------------------------------------------
/dist/font-awesome/css/regular.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | :root, :host {
7 | --fa-style-family-classic: 'Font Awesome 6 Free';
8 | --fa-font-regular: normal 400 1em/1 'Font Awesome 6 Free'; }
9 |
10 | @font-face {
11 | font-family: 'Font Awesome 6 Free';
12 | font-style: normal;
13 | font-weight: 400;
14 | font-display: block;
15 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }
16 |
17 | .far,
18 | .fa-regular {
19 | font-weight: 400; }
20 |
--------------------------------------------------------------------------------
/dist/font-awesome/css/regular.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | :host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-weight:400}
--------------------------------------------------------------------------------
/dist/font-awesome/css/solid.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | :root, :host {
7 | --fa-style-family-classic: 'Font Awesome 6 Free';
8 | --fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; }
9 |
10 | @font-face {
11 | font-family: 'Font Awesome 6 Free';
12 | font-style: normal;
13 | font-weight: 900;
14 | font-display: block;
15 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
16 |
17 | .fas,
18 | .fa-solid {
19 | font-weight: 900; }
20 |
--------------------------------------------------------------------------------
/dist/font-awesome/css/solid.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | :host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}
--------------------------------------------------------------------------------
/dist/font-awesome/css/v4-font-face.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | @font-face {
7 | font-family: 'FontAwesome';
8 | font-display: block;
9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
10 |
11 | @font-face {
12 | font-family: 'FontAwesome';
13 | font-display: block;
14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
15 |
16 | @font-face {
17 | font-family: 'FontAwesome';
18 | font-display: block;
19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");
20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; }
21 |
22 | @font-face {
23 | font-family: 'FontAwesome';
24 | font-display: block;
25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype");
26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; }
27 |
--------------------------------------------------------------------------------
/dist/font-awesome/css/v4-font-face.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}
--------------------------------------------------------------------------------
/dist/font-awesome/css/v5-font-face.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | @font-face {
7 | font-family: 'Font Awesome 5 Brands';
8 | font-display: block;
9 | font-weight: 400;
10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); }
11 |
12 | @font-face {
13 | font-family: 'Font Awesome 5 Free';
14 | font-display: block;
15 | font-weight: 900;
16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); }
17 |
18 | @font-face {
19 | font-family: 'Font Awesome 5 Free';
20 | font-display: block;
21 | font-weight: 400;
22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); }
23 |
--------------------------------------------------------------------------------
/dist/font-awesome/css/v5-font-face.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | * Copyright 2024 Fonticons, Inc.
5 | */
6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}
--------------------------------------------------------------------------------
/dist/font-awesome/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "@fortawesome/fontawesome-free@5.10.2",
3 | "_id": "@fortawesome/fontawesome-free@5.10.2",
4 | "_inBundle": false,
5 | "_integrity": "sha512-9pw+Nsnunl9unstGEHQ+u41wBEQue6XPBsILXtJF/4fNN1L3avJcMF/gGF86rIjeTAgfLjTY9ndm68/X4f4idQ==",
6 | "_location": "/@fortawesome/fontawesome-free",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "version",
10 | "registry": true,
11 | "raw": "@fortawesome/fontawesome-free@5.10.2",
12 | "name": "@fortawesome/fontawesome-free",
13 | "escapedName": "@fortawesome%2ffontawesome-free",
14 | "scope": "@fortawesome",
15 | "rawSpec": "5.10.2",
16 | "saveSpec": null,
17 | "fetchSpec": "5.10.2"
18 | },
19 | "_requiredBy": [
20 | "/"
21 | ],
22 | "_resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.10.2.tgz",
23 | "_shasum": "27e02da1e34b50c9869179d364fb46627b521130",
24 | "_spec": "@fortawesome/fontawesome-free@5.10.2",
25 | "_where": "/Users/DANGER_DAVID/Sites/startbootstrap-themes/startbootstrap-sb-admin-2",
26 | "author": {
27 | "name": "Dave Gandy",
28 | "email": "dave@fontawesome.com",
29 | "url": "http://twitter.com/davegandy"
30 | },
31 | "bugs": {
32 | "url": "http://github.com/FortAwesome/Font-Awesome/issues"
33 | },
34 | "bundleDependencies": false,
35 | "contributors": [
36 | {
37 | "name": "Brian Talbot",
38 | "url": "http://twitter.com/talbs"
39 | },
40 | {
41 | "name": "Travis Chase",
42 | "url": "http://twitter.com/supercodepoet"
43 | },
44 | {
45 | "name": "Rob Madole",
46 | "url": "http://twitter.com/robmadole"
47 | },
48 | {
49 | "name": "Geremia Taglialatela",
50 | "url": "http://twitter.com/gtagliala"
51 | },
52 | {
53 | "name": "Mike Wilkerson",
54 | "url": "http://twitter.com/mw77"
55 | }
56 | ],
57 | "dependencies": {},
58 | "deprecated": false,
59 | "description": "The iconic font, CSS, and SVG framework",
60 | "engines": {
61 | "node": ">=6"
62 | },
63 | "homepage": "https://fontawesome.com",
64 | "keywords": [
65 | "font",
66 | "awesome",
67 | "fontawesome",
68 | "icon",
69 | "svg",
70 | "bootstrap"
71 | ],
72 | "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
73 | "main": "js/fontawesome.js",
74 | "name": "@fortawesome/fontawesome-free",
75 | "repository": {
76 | "type": "git",
77 | "url": "git+https://github.com/FortAwesome/Font-Awesome.git"
78 | },
79 | "style": "css/fontawesome.css",
80 | "version": "5.10.2"
81 | }
82 |
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-v4compatibility.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-v4compatibility.ttf
--------------------------------------------------------------------------------
/dist/font-awesome/webfonts/fa-v4compatibility.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/font-awesome/webfonts/fa-v4compatibility.woff2
--------------------------------------------------------------------------------
/dist/huebee/huebee.css:
--------------------------------------------------------------------------------
1 | /*! Huebee v2.1.0
2 | https://huebee.buzz
3 | ---------------------------------------------- */
4 |
5 | .huebee {
6 | position: absolute;
7 | z-index: 1;
8 | transform: translateY(0px);
9 | transition: opacity 0.15s, transform 0.15s;
10 | }
11 |
12 | .huebee.is-hidden {
13 | opacity: 0;
14 | transform: translateY(10px);
15 | }
16 |
17 | .huebee.is-static-open {
18 | position: relative;
19 | z-index: auto;
20 | }
21 |
22 | .huebee__container {
23 | position: absolute;
24 | left: 0;
25 | top: 5px;
26 | padding: 10px;
27 | background: #EEE;
28 | border-radius: 5px;
29 | box-shadow: 0 5px 10px hsla(0, 0%, 0%, 0.3);
30 | }
31 |
32 | .huebee.is-static-open .huebee__container {
33 | position: relative;
34 | display: inline-block;
35 | left: auto;
36 | top: auto;
37 | box-shadow: none;
38 | }
39 |
40 | .huebee__canvas {
41 | display: block;
42 | cursor: pointer;
43 | }
44 |
45 | .huebee__cursor {
46 | width: 15px;
47 | height: 15px;
48 | position: absolute;
49 | left: 0px;
50 | top: 0px;
51 | box-sizing: content-box;
52 | border: 3px solid white;
53 | border-radius: 5px;
54 | pointer-events: none;
55 | }
56 |
57 | .huebee__cursor.is-hidden { opacity: 0; }
58 |
59 | .huebee__close-button {
60 | display: block;
61 | position: absolute;
62 | width: 24px;
63 | height: 24px;
64 | top: -9px;
65 | right: -9px;
66 | border-radius: 12px;
67 | background: #222;
68 | }
69 |
70 | .huebee__close-button__x {
71 | stroke: white;
72 | stroke-width: 3;
73 | stroke-linecap: round;
74 | }
75 |
76 | .huebee__close-button:hover {
77 | background: white;
78 | cursor: pointer;
79 | }
80 |
81 | .huebee__close-button:hover .huebee__close-button__x {
82 | stroke: #222;
83 | }
84 |
--------------------------------------------------------------------------------
/dist/huebee/huebee.min.css:
--------------------------------------------------------------------------------
1 | /*! Huebee v2.1.0
2 | https://huebee.buzz
3 | ---------------------------------------------- */
4 | .huebee{position:absolute;z-index:1;transform:translateY(0);transition:opacity .15s,transform .15s}.huebee.is-hidden{opacity:0;transform:translateY(10px)}.huebee.is-static-open{position:relative;z-index:auto}.huebee__container{position:absolute;left:0;top:5px;padding:10px;background:#eee;border-radius:5px;box-shadow:0 5px 10px hsla(0,0%,0%,.3)}.huebee.is-static-open .huebee__container{position:relative;display:inline-block;left:auto;top:auto;box-shadow:none}.huebee__canvas{display:block;cursor:pointer}.huebee__cursor{width:15px;height:15px;position:absolute;left:0;top:0;box-sizing:content-box;border:3px solid #fff;border-radius:5px;pointer-events:none}.huebee__cursor.is-hidden{opacity:0}.huebee__close-button{display:block;position:absolute;width:24px;height:24px;top:-9px;right:-9px;border-radius:12px;background:#222}.huebee__close-button__x{stroke:#fff;stroke-width:3;stroke-linecap:round}.huebee__close-button:hover{background:#fff;cursor:pointer}.huebee__close-button:hover .huebee__close-button__x{stroke:#222}
--------------------------------------------------------------------------------
/dist/jquery-easing/jquery.easing.compatibility.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Easing Compatibility v1 - http://gsgd.co.uk/sandbox/jquery/easing
3 | *
4 | * Adds compatibility for applications that use the pre 1.2 easing names
5 | *
6 | * Copyright (c) 2007 George Smith
7 | * Licensed under the MIT License:
8 | * http://www.opensource.org/licenses/mit-license.php
9 | */
10 |
11 | (function($){
12 | $.extend( $.easing,
13 | {
14 | easeIn: function (x, t, b, c, d) {
15 | return $.easing.easeInQuad(x, t, b, c, d);
16 | },
17 | easeOut: function (x, t, b, c, d) {
18 | return $.easing.easeOutQuad(x, t, b, c, d);
19 | },
20 | easeInOut: function (x, t, b, c, d) {
21 | return $.easing.easeInOutQuad(x, t, b, c, d);
22 | },
23 | expoin: function(x, t, b, c, d) {
24 | return $.easing.easeInExpo(x, t, b, c, d);
25 | },
26 | expoout: function(x, t, b, c, d) {
27 | return $.easing.easeOutExpo(x, t, b, c, d);
28 | },
29 | expoinout: function(x, t, b, c, d) {
30 | return $.easing.easeInOutExpo(x, t, b, c, d);
31 | },
32 | bouncein: function(x, t, b, c, d) {
33 | return $.easing.easeInBounce(x, t, b, c, d);
34 | },
35 | bounceout: function(x, t, b, c, d) {
36 | return $.easing.easeOutBounce(x, t, b, c, d);
37 | },
38 | bounceinout: function(x, t, b, c, d) {
39 | return $.easing.easeInOutBounce(x, t, b, c, d);
40 | },
41 | elasin: function(x, t, b, c, d) {
42 | return $.easing.easeInElastic(x, t, b, c, d);
43 | },
44 | elasout: function(x, t, b, c, d) {
45 | return $.easing.easeOutElastic(x, t, b, c, d);
46 | },
47 | elasinout: function(x, t, b, c, d) {
48 | return $.easing.easeInOutElastic(x, t, b, c, d);
49 | },
50 | backin: function(x, t, b, c, d) {
51 | return $.easing.easeInBack(x, t, b, c, d);
52 | },
53 | backout: function(x, t, b, c, d) {
54 | return $.easing.easeOutBack(x, t, b, c, d);
55 | },
56 | backinout: function(x, t, b, c, d) {
57 | return $.easing.easeInOutBack(x, t, b, c, d);
58 | }
59 | });})(jQuery);
60 |
--------------------------------------------------------------------------------
/dist/jquery-easing/jquery.easing.min.js:
--------------------------------------------------------------------------------
1 | (function(factory){if(typeof define==="function"&&define.amd){define(["jquery"],function($){return factory($)})}else if(typeof module==="object"&&typeof module.exports==="object"){exports=factory(require("jquery"))}else{factory(jQuery)}})(function($){$.easing.jswing=$.easing.swing;var pow=Math.pow,sqrt=Math.sqrt,sin=Math.sin,cos=Math.cos,PI=Math.PI,c1=1.70158,c2=c1*1.525,c3=c1+1,c4=2*PI/3,c5=2*PI/4.5;function bounceOut(x){var n1=7.5625,d1=2.75;if(x<1/d1){return n1*x*x}else if(x<2/d1){return n1*(x-=1.5/d1)*x+.75}else if(x<2.5/d1){return n1*(x-=2.25/d1)*x+.9375}else{return n1*(x-=2.625/d1)*x+.984375}}$.extend($.easing,{def:"easeOutQuad",swing:function(x){return $.easing[$.easing.def](x)},easeInQuad:function(x){return x*x},easeOutQuad:function(x){return 1-(1-x)*(1-x)},easeInOutQuad:function(x){return x<.5?2*x*x:1-pow(-2*x+2,2)/2},easeInCubic:function(x){return x*x*x},easeOutCubic:function(x){return 1-pow(1-x,3)},easeInOutCubic:function(x){return x<.5?4*x*x*x:1-pow(-2*x+2,3)/2},easeInQuart:function(x){return x*x*x*x},easeOutQuart:function(x){return 1-pow(1-x,4)},easeInOutQuart:function(x){return x<.5?8*x*x*x*x:1-pow(-2*x+2,4)/2},easeInQuint:function(x){return x*x*x*x*x},easeOutQuint:function(x){return 1-pow(1-x,5)},easeInOutQuint:function(x){return x<.5?16*x*x*x*x*x:1-pow(-2*x+2,5)/2},easeInSine:function(x){return 1-cos(x*PI/2)},easeOutSine:function(x){return sin(x*PI/2)},easeInOutSine:function(x){return-(cos(PI*x)-1)/2},easeInExpo:function(x){return x===0?0:pow(2,10*x-10)},easeOutExpo:function(x){return x===1?1:1-pow(2,-10*x)},easeInOutExpo:function(x){return x===0?0:x===1?1:x<.5?pow(2,20*x-10)/2:(2-pow(2,-20*x+10))/2},easeInCirc:function(x){return 1-sqrt(1-pow(x,2))},easeOutCirc:function(x){return sqrt(1-pow(x-1,2))},easeInOutCirc:function(x){return x<.5?(1-sqrt(1-pow(2*x,2)))/2:(sqrt(1-pow(-2*x+2,2))+1)/2},easeInElastic:function(x){return x===0?0:x===1?1:-pow(2,10*x-10)*sin((x*10-10.75)*c4)},easeOutElastic:function(x){return x===0?0:x===1?1:pow(2,-10*x)*sin((x*10-.75)*c4)+1},easeInOutElastic:function(x){return x===0?0:x===1?1:x<.5?-(pow(2,20*x-10)*sin((20*x-11.125)*c5))/2:pow(2,-20*x+10)*sin((20*x-11.125)*c5)/2+1},easeInBack:function(x){return c3*x*x*x-c1*x*x},easeOutBack:function(x){return 1+c3*pow(x-1,3)+c1*pow(x-1,2)},easeInOutBack:function(x){return x<.5?pow(2*x,2)*((c2+1)*2*x-c2)/2:(pow(2*x-2,2)*((c2+1)*(x*2-2)+c2)+2)/2},easeInBounce:function(x){return 1-bounceOut(1-x)},easeOutBounce:bounceOut,easeInOutBounce:function(x){return x<.5?(1-bounceOut(1-2*x))/2:(1+bounceOut(2*x-1))/2}})});
--------------------------------------------------------------------------------
/dist/raspap/css/fonts/RaspAP.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/raspap/css/fonts/RaspAP.eot
--------------------------------------------------------------------------------
/dist/raspap/css/fonts/RaspAP.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/raspap/css/fonts/RaspAP.ttf
--------------------------------------------------------------------------------
/dist/raspap/css/fonts/RaspAP.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/dist/raspap/css/fonts/RaspAP.woff
--------------------------------------------------------------------------------
/dist/raspap/css/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'RaspAP';
3 | src: url('fonts/RaspAP.eot?hszbb1');
4 | src: url('fonts/RaspAP.eot?hszbb1#iefix') format('embedded-opentype'),
5 | url('fonts/RaspAP.ttf?hszbb1') format('truetype'),
6 | url('fonts/RaspAP.woff?hszbb1') format('woff'),
7 | url('fonts/RaspAP.svg?hszbb1#RaspAP') format('svg');
8 | font-weight: normal;
9 | font-style: normal;
10 | font-display: block;
11 | }
12 |
13 | [class^="ra-"], [class*=" ra-"] {
14 | /* use !important to prevent issues with browser extensions that change fonts */
15 | font-family: 'RaspAP' !important;
16 | speak: never;
17 | font-style: normal;
18 | font-weight: normal;
19 | font-variant: normal;
20 | text-transform: none;
21 | line-height: 1;
22 |
23 | /* Better Font Rendering =========== */
24 | -webkit-font-smoothing: antialiased;
25 | -moz-osx-font-smoothing: grayscale;
26 | }
27 |
28 | .ra-wireguard:before {
29 | font-size: 1.1rem;
30 | content: "\e900";
31 | vertical-align: middle;
32 | }
33 | .ra-raspap:before {
34 | content: "\e901";
35 | color: #2b8080;
36 | margin-left: 0.1em;
37 | }
38 | .ra-tailscale:before {
39 | font-size: 1.1rem;
40 | content: "\e902";
41 | vertical-align: top;
42 | }
43 |
44 | .card-header .ra-wireguard:before,
45 | .card-header .ra-tailscale:before {
46 | color: #fff;
47 | }
48 |
49 | .sidebar .nav-item.active .nav-link span.ra-wireguard:before,
50 | .sidebar .nav-item.active .nav-link span.ra-tailscale:before {
51 | color: #6e707e;
52 | }
53 |
54 | .sb-nav-link-icon .ra-tailscale {
55 | margin-bottom: 0.4rem;
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/dist/sb-admin/js/scripts.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - SB Admin v7.0.7 (https://startbootstrap.com/template/sb-admin)
3 | * Copyright 2013-2023 Start Bootstrap
4 | * Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-sb-admin/blob/master/LICENSE)
5 | */
6 | //
7 | // Scripts
8 | //
9 |
10 | window.addEventListener('DOMContentLoaded', event => {
11 |
12 | // Toggle the side navigation
13 | const sidebarToggle = document.body.querySelector('#sidebarToggle');
14 | if (sidebarToggle) {
15 | // Uncomment below to persist sidebar toggle between refreshes
16 | if (localStorage.getItem('sb|sidebar-toggle') === 'true') {
17 | document.body.classList.toggle('sb-sidenav-toggled');
18 | }
19 | sidebarToggle.addEventListener('click', event => {
20 | event.preventDefault();
21 | document.body.classList.toggle('sb-sidenav-toggled');
22 | localStorage.setItem('sb|sidebar-toggle', document.body.classList.contains('sb-sidenav-toggled'));
23 | });
24 | }
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/favicon.ico
--------------------------------------------------------------------------------
/includes/CSRF.php:
--------------------------------------------------------------------------------
1 | getToken();
25 | }
26 |
27 | public static function verify(): bool
28 | {
29 | if (!isset($_POST['csrf_token'])) {
30 | return false;
31 | }
32 | return self::instance()->csrfValidateRequest() &&
33 | self::instance()->CSRFValidate($_POST['csrf_token']);
34 | }
35 |
36 | public static function metaTag(): string
37 | {
38 | return self::instance()->CSRFMetaTag();
39 | }
40 |
41 | public static function hiddenField(): string
42 | {
43 | return self::instance()->CSRFTokenFieldTag();
44 | }
45 |
46 | public static function handleInvalidToken(): void
47 | {
48 | self::instance()->handleInvalidCSRFToken();
49 | }
50 |
51 | /**
52 | * Validates a CSRF Request
53 | *
54 | * @return bool
55 | */
56 | public static function validateRequest(): bool
57 | {
58 | $methods = ['POST', 'PUT', 'DELETE', 'PATCH'];
59 | return in_array($_SERVER['REQUEST_METHOD'], $methods) &&
60 | self::instance()->csrfValidateRequest();
61 | }
62 | }
63 |
64 | if (\RaspAP\Tokens\CSRF::validateRequest()) {
65 | if (!\RaspAP\Tokens\CSRF::verify()) {
66 | error_log("CSRF verification failed: Token missing or invalid");
67 | \RaspAP\Tokens\CSRF::handleInvalidToken();
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/includes/about.php:
--------------------------------------------------------------------------------
1 | text($strContent);
13 |
14 | $strContent = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/CONTRIBUTING.md');
15 | $contributingHtml = $Parsedown->text($strContent);
16 |
17 | echo renderTemplate(
18 | "about", compact(
19 | 'sponsorsHtml',
20 | 'contributingHtml'
21 | )
22 | );
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/includes/admin.php:
--------------------------------------------------------------------------------
1 | getAuthConfig();
8 | $username = $config['admin_user'];
9 | $password = $config['admin_pass'];
10 |
11 | if (isset($_POST['UpdateAdminPassword'])) {
12 | if (password_verify($_POST['oldpass'], $password)) {
13 | $new_username=trim($_POST['username']);
14 | if ($_POST['newpass'] !== $_POST['newpassagain']) {
15 | $status->addMessage('New passwords do not match', 'danger');
16 | } elseif ($new_username == '') {
17 | $status->addMessage('Username must not be empty', 'danger');
18 | } else {
19 | if (!file_exists(RASPI_ADMIN_DETAILS)) {
20 | $tmpauth = fopen(RASPI_ADMIN_DETAILS, 'w');
21 | fclose($tmpauth);
22 | }
23 |
24 | if ($auth_file = fopen(RASPI_ADMIN_DETAILS, 'w')) {
25 | fwrite($auth_file, $new_username.PHP_EOL);
26 | fwrite($auth_file, password_hash($_POST['newpass'], PASSWORD_BCRYPT).PHP_EOL);
27 | fclose($auth_file);
28 | $username = $new_username;
29 | $_SESSION['user_id'] = $username;
30 | $status->addMessage('Admin password updated');
31 | } else {
32 | $status->addMessage('Failed to update admin password', 'danger');
33 | }
34 | }
35 | } else {
36 | $status->addMessage('Old password does not match', 'danger');
37 | }
38 | } elseif (isset($_POST['logout'])) {
39 | $auth->logout();
40 | }
41 |
42 | echo renderTemplate(
43 | "admin", compact(
44 | "status",
45 | "username"
46 | )
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/includes/authenticate.php:
--------------------------------------------------------------------------------
1 | isLogged()) {
7 | $auth->authenticate();
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/includes/autoload.php:
--------------------------------------------------------------------------------
1 | $interfacesWlo ]);
10 |
11 | $extraFooterScripts[] = array('src'=>'dist/datatables/jquery.dataTables.min.js', 'defer'=>false);
12 | $extraFooterScripts[] = array('src'=>'app/js/bandwidthcharts.js', 'defer'=>false);
13 | }
14 |
--------------------------------------------------------------------------------
/includes/footer.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
v |
6 |
%s'), 'https://github.com/RaspAP', _('RaspAP Team')); ?>
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/includes/login.php:
--------------------------------------------------------------------------------
1 | login($username, $password)) {
24 | $config = $auth->getAuthConfig();
25 | header('Location: ' . $redirectUrl);
26 | die();
27 | } else {
28 | $status = "Login failed";
29 | }
30 | }
31 | }
32 |
33 | echo renderTemplate(
34 | "login", compact(
35 | "status",
36 | "redirectUrl"
37 | )
38 | );
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/includes/navbar.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | RaspAP
4 |
5 |
6 |
7 |
21 |
22 |
--------------------------------------------------------------------------------
/includes/networking.php:
--------------------------------------------------------------------------------
1 | handlePageAction($page)) {
11 | // If no plugin is available fall back to core page action handlers
12 | handleCorePageAction($page, $extraFooterScripts);
13 | }
14 |
15 | /**
16 | * Core application page handling
17 | *
18 | * @param string $page
19 | * @param array $extraFooterScripts
20 | * @return void
21 | */
22 | function handleCorePageAction(string $page, array &$extraFooterScripts): void
23 | {
24 | switch ($page) {
25 | case "/wlan0_info":
26 | DisplayDashboard($extraFooterScripts);
27 | break;
28 | case "/dhcpd_conf":
29 | DisplayDHCPConfig();
30 | break;
31 | case "/wpa_conf":
32 | DisplayWPAConfig();
33 | break;
34 | case "/network_conf":
35 | DisplayNetworkingConfig();
36 | break;
37 | case "/hostapd_conf":
38 | DisplayHostAPDConfig();
39 | break;
40 | case "/adblock_conf":
41 | DisplayAdBlockConfig();
42 | break;
43 | case "/openvpn_conf":
44 | DisplayOpenVPNConfig();
45 | break;
46 | case "/wg_conf":
47 | DisplayWireGuardConfig();
48 | break;
49 | case "/provider_conf":
50 | DisplayProviderConfig();
51 | break;
52 | case "/torproxy_conf":
53 | DisplayTorProxyConfig();
54 | break;
55 | case "/auth_conf":
56 | DisplayAuthConfig($_SESSION['user_id']);
57 | break;
58 | case "/save_hostapd_conf":
59 | SaveTORAndVPNConfig();
60 | break;
61 | case "/data_use":
62 | DisplayDataUsage($extraFooterScripts);
63 | break;
64 | case "/system_info":
65 | DisplaySystem($extraFooterScripts);
66 | break;
67 | case "/restapi_conf":
68 | DisplayRestAPI();
69 | break;
70 | case "/about":
71 | DisplayAbout();
72 | break;
73 | case "/login":
74 | DisplayLogin();
75 | break;
76 | default:
77 | DisplayDashboard($extraFooterScripts);
78 | }
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/includes/session.php:
--------------------------------------------------------------------------------
1 | getSidebar();
14 | $sidebar->render();
15 |
16 |
--------------------------------------------------------------------------------
/includes/sysstats.php:
--------------------------------------------------------------------------------
1 | hostname();
6 | $uptime = $system->uptime();
7 | $cores = $system->processorCount();
8 |
9 | // mem used
10 | $memused = $system->usedMemory();
11 | $memused_status = "primary";
12 | if ($memused > 90) {
13 | $memused_status = "danger";
14 | $memused_led = "service-status-down";
15 | } elseif ($memused > 75) {
16 | $memused_status = "warning";
17 | $memused_led = "service-status-warn";
18 | } elseif ($memused > 0) {
19 | $memused_status = "success";
20 | $memused_led = "service-status-up";
21 | }
22 |
23 | // cpu load
24 | $cpuload = $system->systemLoadPercentage();
25 | if ($cpuload > 90) {
26 | $cpuload_status = "danger";
27 | } elseif ($cpuload > 75) {
28 | $cpuload_status = "warning";
29 | } elseif ($cpuload >= 0) {
30 | $cpuload_status = "success";
31 | }
32 |
33 | // cpu temp
34 | $cputemp = $system->systemTemperature();
35 | if ($cputemp > 70) {
36 | $cputemp_status = "danger";
37 | $cputemp_led = "service-status-down";
38 | } elseif ($cputemp > 50) {
39 | $cputemp_status = "warning";
40 | $cputemp_led = "service-status-warn";
41 | } else {
42 | $cputemp_status = "success";
43 | $cputemp_led = "service-status-up";
44 | }
45 |
46 | // hostapd status
47 | $hostapd = $system->hostapdStatus();
48 | if ($hostapd[0] ==1) {
49 | $hostapd_status = "up";
50 | $hostapd_led = "service-status-up";
51 | } else {
52 | $hostapd_status = "down";
53 | $hostapd_led = "service-status-warn";
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/installers/configauth.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Updates openvpn client.conf with auth credentials,
4 | # adds iptables rules to forward traffic from tun0
5 | # to configured wireless interface
6 | # @author billz
7 | # license: GNU General Public License v3.0
8 |
9 | # Exit on error
10 | set -o errexit
11 | # Exit on error inside functions
12 | set -o errtrace
13 | # Turn on traces, disabled by default
14 | #set -o xtrace
15 |
16 | file=$1
17 | auth=$2
18 | interface=$3
19 | readonly rulesv4="/etc/iptables/rules.v4"
20 |
21 | if [ "$auth" = 1 ]; then
22 | echo "Enabling auth-user-pass in OpenVPN client.conf"
23 | line='auth-user-pass'
24 | if grep -q "$line" $file; then
25 | echo "Updating $line"
26 | sudo sed -i "s/$line/$line login.conf/g" $file
27 | else
28 | echo "Adding $line"
29 | sudo sed -i "$ a $line login.conf" $file
30 | fi
31 | fi
32 |
33 | # Configure NAT and forwarding with iptables
34 | echo "Checking iptables rules"
35 | rules=(
36 | "-A POSTROUTING -o tun0 -j MASQUERADE"
37 | "-A FORWARD -i tun0 -o ${interface} -m state --state RELATED,ESTABLISHED -j ACCEPT"
38 | "-A FORWARD -i ${interface} -o tun0 -j ACCEPT"
39 | )
40 |
41 | for rule in "${rules[@]}"; do
42 | if grep -- "$rule" $rulesv4 > /dev/null; then
43 | echo "Rule already exits: ${rule}"
44 | else
45 | rule=$(sed -e 's/^\(-A POSTROUTING\)/-t nat \1/' <<< $rule)
46 | echo "Adding rule: ${rule}"
47 | sudo iptables $rule
48 | added=true
49 | fi
50 | done
51 |
52 | if [ "$added" = true ]; then
53 | echo "Persisting IP tables rules"
54 | sudo iptables-save | sudo tee $rulesv4 > /dev/null
55 | fi
56 |
57 |
--------------------------------------------------------------------------------
/installers/configport.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Updates lighttpd config settings and restarts the service
4 | # @author billz
5 | # license: GNU General Public License v3.0
6 |
7 | # Exit on error
8 | set -o errexit
9 | # Exit on error inside functions
10 | set -o errtrace
11 | # Turn on traces, disabled by default
12 | #set -o xtrace
13 |
14 | server_port=$1
15 | server_bind=$2
16 | lighttpd_conf=$3
17 | host=$4
18 | restart_service=0
19 |
20 | while :; do
21 | case $1 in
22 | -r|--restart)
23 | restart_service=1
24 | shift
25 | ;;
26 | *)
27 | break
28 | ;;
29 | esac
30 | done
31 |
32 | if [ "$restart_service" = 1 ]; then
33 | echo "Restarting lighttpd in 3 seconds..."
34 | sleep 3
35 | systemctl restart lighttpd.service
36 | fi
37 | if [ -n "$server_port" ]; then
38 | echo "Changing lighttpd server.port to $server_port ..."
39 | sed -i "s/^\(server\.port *= *\)[0-9]*/\1$server_port/g" "$lighttpd_conf"
40 | echo "RaspAP will now be available at port $server_port"
41 | conf_change=1
42 | fi
43 | if [ -n "$server_bind" ]; then
44 | echo "Changing lighttpd server.bind to $server_bind ..."
45 | grep -q 'server.bind' "$lighttpd_conf" && \
46 | sed -i "s/^\(server\.bind.*= \)\".*\"*/\1\"$server_bind\"/g" "$lighttpd_conf" || \
47 | printf "server.bind \t\t\t\t = \"$server_bind\"\n" >> "$lighttpd_conf"
48 | echo "RaspAP will now be available at address $server_bind"
49 | conf_change=1
50 | fi
51 | if [ "$conf_change" == 1 ]; then
52 | echo "Restart lighttpd for new settings to take effect"
53 | fi
54 |
55 |
--------------------------------------------------------------------------------
/installers/dhcpcd.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=DHCP Client Daemon
3 | Wants=network.target
4 | Before=network-online.target
5 | Documentation=man:dhcpcd(8)
6 |
7 | [Service]
8 | Type=forking
9 | ExecStart=/usr/sbin/dhcpcd -b -q
10 | Restart=always
11 |
12 | [Install]
13 | WantedBy=multi-user.target
14 |
15 |
--------------------------------------------------------------------------------
/installers/disablelog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | /bin/sed -i 's|DAEMON_OPTS=" -f /tmp/hostapd.log"|#DAEMON_OPTS=""|' /etc/default/hostapd
3 |
4 |
--------------------------------------------------------------------------------
/installers/enablelog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | /bin/sed -i 's|#DAEMON_OPTS=""|DAEMON_OPTS=" -f /tmp/hostapd.log"|' /etc/default/hostapd
3 | touch /tmp/hostapd.log
4 |
--------------------------------------------------------------------------------
/installers/install_feature_clients.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # RaspAP feature installation: handling of mobile data clients and client configuration
4 | # to be sources by the RaspAP installer script
5 | # Author: @zbchristian
6 | # Author URI: https://github.com/zbchristian/
7 | # License: GNU General Public License v3.0
8 | # License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 |
10 | # path for mobile modem scripts
11 | readonly raspap_clients_scripts="/usr/local/sbin"
12 | #
13 | # table of mobile network operators - links the 5 digit operator code (from the modem) with a clear text operator name
14 | readonly raspap_clients_operator_table="https://raw.githubusercontent.com/musalbas/mcc-mnc-table/master/mcc-mnc-table.csv"
15 |
16 | function _install_feature_clients() {
17 | name="feature clients"
18 |
19 | _install_log "Install $name"
20 |
21 | _install_log " - required packages for mobile data clients"
22 | sudo apt-get -y install wvdial socat bc || _install_status 1 "Unable to install dependencies for $name"
23 |
24 | _install_log " - copy configuration files and scripts"
25 | # Move scripts
26 | sudo cp "$webroot_dir/config/client_config/"*.sh "$raspap_clients_scripts/" || _install_status 1 "Unable to move client scripts ($name)"
27 | sudo chmod a+rx "$raspap_clients_scripts/"*.sh || _install_status 1 "Unable to chmod client scripts ($name)"
28 | # wget $raspap_clients_operator_table -o "$raspap_clients_scripts/"mcc-mnc-table.csv || _install_status 1 "Unable to wget operator table ($name)"
29 | sudo cp "$webroot_dir/config/client_config/mcc-mnc-table.csv" "$raspap_clients_scripts/" || _install_status 1 "Unable to move client data ($name)"
30 | # wvdial settings
31 | sudo cp "$webroot_dir/config/client_config/wvdial.conf" "/etc/" || _install_status 1 "Unable to install client configuration ($name)"
32 | sudo cp "$webroot_dir/config/client_config/interfaces" "/etc/network/interfaces" || _install_status 1 "Unable to install interface settings ($name)"
33 | # udev rules/services to auto start mobile data services
34 | sudo cp "$webroot_dir/config/client_config/70-mobile-data-sticks.rules" "/etc/udev/rules.d/" || _install_status 1 "Unable to install client udev rules ($name)"
35 | sudo cp "$webroot_dir/config/client_config/80-raspap-net-devices.rules" "/etc/udev/rules.d/" || _install_status 1 "Unable to install client udev rules ($name)"
36 | sudo cp "$webroot_dir/config/client_config/"*.service "/etc/systemd/system/" || _install_status 1 "Unable to install client startup services ($name)"
37 | # client configuration and udev rule templates
38 | sudo cp "$webroot_dir/config/client_udev_prototypes.json" "/etc/raspap/networking/" || _install_status 1 "Unable to install client configuration ($name)"
39 | _install_status 0
40 | }
41 |
--------------------------------------------------------------------------------
/installers/install_feature_firewall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # RaspAP feature installation: Firewall
4 | # to be sources by the RaspAP installer script
5 | # Author: @zbchristian
6 | # Author URI: https://github.com/zbchristian/
7 | # License: GNU General Public License v3.0
8 | # License URI: https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 |
10 | function _install_feature_firewall() {
11 | name="feature firewall"
12 |
13 | _install_log "Install $name"
14 | # create config dir
15 | sudo mkdir "$raspap_network/firewall" || _install_status 1 "Unable to create firewall config directory"
16 | # copy firewall configuration
17 | sudo cp "$webroot_dir/config/iptables_rules.json" "$raspap_network/firewall/" || _install_status 1 "Unable to copy iptables templates"
18 | sudo chown $raspap_user:$raspap_user -R "$raspap_network/firewall" || _install_status 1 "Unable to change ownership of firewall directory and files "
19 | _install_status 0
20 | }
21 |
--------------------------------------------------------------------------------
/installers/openvpnlog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | touch /tmp/openvpn.log
3 | journalctl -n 500 |grep "openvpn\[" | sudo tee /tmp/openvpn.log
4 |
--------------------------------------------------------------------------------
/installers/raspap-network-activity@.service:
--------------------------------------------------------------------------------
1 | # Author: BillZ
2 |
3 | [Unit]
4 | Description=RaspAP Network Activity Monitor for %I
5 | After=network.target
6 |
7 | [Service]
8 | ExecStart=/usr/local/bin/raspap-network-monitor %i
9 | Restart=always
10 | RestartSec=2
11 | User=root
12 |
13 | [Install]
14 | WantedBy=multi-user.target
15 |
16 |
--------------------------------------------------------------------------------
/installers/raspapd.service:
--------------------------------------------------------------------------------
1 | ### BEGIN INIT INFO
2 | # Provides: raspapd
3 | # Required-Start: $remote_fs $syslog
4 | # Required-Stop: $remote_fs $syslog
5 | # Default-Start: S 2 3 4 5
6 | # Default-Stop: 0 1 6
7 | # Short-Description: Start RaspAP daemon at boot time
8 | # Description: Enable service provided by daemon
9 | ### END INIT INFO
10 | # Author: BillZ
11 |
12 | [Unit]
13 | Description=RaspAP Service Daemon
14 | DefaultDependencies=no
15 | After=multi-user.target
16 |
17 | [Service]
18 | Type=oneshot
19 | ExecStart=/bin/bash /etc/raspap/hostapd/servicestart.sh --seconds 1
20 | RemainAfterExit=no
21 |
22 | [Install]
23 | WantedBy=multi-user.target
24 |
25 |
--------------------------------------------------------------------------------
/installers/restapi.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=raspap-restapi
3 | After=network.target
4 |
5 | [Service]
6 | User=pi
7 | WorkingDirectory=/etc/raspap/api
8 | LimitNOFILE=4096
9 | ExecStart=/usr/bin/python3 -m uvicorn main:app --host 0.0.0.0 --port 8081
10 | ExecStop=/bin/kill -HUP ${MAINPID}
11 | Restart=on-failure
12 | RestartSec=5s
13 |
14 | [Install]
15 | WantedBy=multi-user.target
16 |
17 |
--------------------------------------------------------------------------------
/installers/toggle-bridged-routed.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function do_routed_mode() {
4 | sudo systemctl disable systemd-networkd
5 |
6 | sudo sed -i "s/^.*#BRIDGED$/#&/" /etc/dhcpcd.conf
7 | sudo sed -i "s/^bridge/#&/" /etc/hostapd/hostapd.conf
8 |
9 | sudo ip link set down br0
10 | sudo ip link del dev br0
11 | }
12 |
13 | function do_bridged_mode() {
14 | sudo sed -i "s/^#\(.*#BRIDGED\)$/\1/" /etc/dhcpcd.conf
15 | sudo sed -i "s/^#\(bridge\)/\1/" /etc/hostapd/hostapd.conf
16 |
17 | sudo ip link set down eth0
18 | sudo ip link set up eth0
19 |
20 | sudo systemctl start systemd-networkd
21 | sudo systemctl enable systemd-networkd
22 | }
23 |
24 | sudo systemctl stop systemd-networkd
25 | sudo systemctl stop hostapd
26 | sudo systemctl stop dhcpcd
27 | sudo systemctl stop dnsmasq
28 |
29 | if [ "$1" = "force-routed" ]
30 | then do_routed_mode
31 | elif [ "$1" = "force-bridged" ]
32 | then do_bridged_mode
33 | elif ip addr show br0 | grep 'inet ' > /dev/null
34 | then do_routed_mode
35 | elif ! ip addr show br0 | grep 'inet ' > /dev/null
36 | then do_bridged_mode
37 | fi
38 |
39 | sudo systemctl start hostapd
40 | sudo systemctl start dhcpcd
41 | sudo systemctl start dnsmasq
42 |
--------------------------------------------------------------------------------
/installers/update_blocklist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | #
4 | # @author billz
5 | # license: GNU General Public License v3.0
6 |
7 | # Exit on error
8 | set -o errexit
9 | # Exit on error inside functions
10 | set -o errtrace
11 | # Turn on traces, disabled by default
12 | #set -o xtrace
13 |
14 | update_url=$1
15 | file=$2
16 | destination=$3
17 |
18 | wget -q --no-use-server-timestamps ${update_url} -O ${destination}${file} &> /dev/null
19 |
20 | echo "$?"
21 |
22 |
--------------------------------------------------------------------------------
/installers/update_firewall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # include the raspap helper functions
3 | source /usr/local/sbin/raspap_helpers.sh
4 |
5 | _getWebRoot
6 |
7 | echo -n "Update firewall ... "
8 |
9 | cat << EOF > /tmp/updateFirewall.php
10 |
25 | EOF
26 |
27 | sudo php -d include_path=$raspap_webroot /tmp/updateFirewall.php
28 | rm /tmp/updateFirewall.php
29 | echo "done."
30 |
--------------------------------------------------------------------------------
/locale/cs_CZ/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/cs_CZ/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/da_DK/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/da_DK/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/de_DE/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/de_DE/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/el_GR/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/el_GR/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/en_US/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/en_US/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/es_MX/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/es_MX/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/fi_FI/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/fi_FI/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/fr_FR/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/fr_FR/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/id_ID/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/id_ID/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/it_IT/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/it_IT/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/ja_JP/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/ja_JP/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/ko_KR/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/ko_KR/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/nl_NL/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/nl_NL/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/pl_PL/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/pl_PL/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/pocompile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Compiles portable object (.po) files into machine object (.mo) files
4 | # Requires GNU gettext
5 | # Install with: apt-get install gettext
6 |
7 | arrLocales=($PWD/*/);
8 |
9 | # compiles message catalogs to binary format
10 | for f in "${arrLocales[@]}"; do
11 | echo -n `msgfmt -o ${f}LC_MESSAGES/messages.mo ${f}LC_MESSAGES/messages.po`
12 | echo "Compiled ${f}LC_MESSAGES/messages.po"
13 | done
14 |
15 |
--------------------------------------------------------------------------------
/locale/pt_BR/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/pt_BR/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/ro_RO/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/ro_RO/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/ru_RU/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/ru_RU/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/sk_SK/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/sk_SK/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/sv_SE/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/sv_SE/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/tr_TR/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/tr_TR/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/vi_VN/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/vi_VN/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/zh_CN/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/zh_CN/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/locale/zh_TW/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaspAP/raspap-webgui/1b39a7a1bf8a3c02bbb106a7ce2861f9858428ab/locale/zh_TW/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "RaspAP WiFi Configuration Portal",
3 | "name": "raspap",
4 | "version": "2.6",
5 | "scripts": {
6 | "start": "node_modules/.bin/gulp watch"
7 | },
8 | "description": "Simple wireless AP setup & management for Debian-based devices",
9 | "keywords": [
10 | "raspberry-pi",
11 | "hostapd",
12 | "raspap",
13 | "wifi",
14 | "lighttpd",
15 | "dnsmasq",
16 | "admin",
17 | "app"
18 | ],
19 | "homepage": "https://github.com/raspap/raspap-webgui",
20 | "bugs": {
21 | "url": "https://github.com/raspap/raspap-webgui/issues"
22 | },
23 | "license": "GPL-3.0",
24 | "author": "RaspAP Developers",
25 | "contributors": [
26 | "Bill Zimmerman (https://github.com/billz)",
27 | "Lawrence Yau (https://github.com/SirLagz)"
28 | ],
29 | "repository": {
30 | "type": "git",
31 | "url": "https://github.com/raspap/raspap-webgui.git"
32 | },
33 | "publishConfig": {
34 | "registry": "https://npm.pkg.github.com/"
35 | },
36 | "dependencies": {
37 | "browser-sync": "^2.26.7",
38 | "del": "^5.1.0",
39 | "gulp": "^4.0.2",
40 | "gulp-autoprefixer": "^7.0.1",
41 | "gulp-clean-css": "^4.3.0",
42 | "gulp-header": "^2.0.9",
43 | "gulp-plumber": "^1.2.1",
44 | "gulp-rename": "^2.0.0",
45 | "gulp-uglify": "^3.0.2",
46 | "huebee": "^2.1.0",
47 | "jquery": "^3.5.0",
48 | "merge-stream": "^2.0.0",
49 | "node-gyp": "^7.0.0",
50 | "startbootstrap-sb-admin-2": "4.0.7"
51 | },
52 | "devDependencies": {
53 | "gulp-sass": "^4.0.2"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/RaspAP/DotEnv/DotEnv.php:
--------------------------------------------------------------------------------
1 |
8 | * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 | */
10 |
11 | declare(strict_types=1);
12 |
13 | namespace RaspAP\DotEnv;
14 |
15 | class DotEnv
16 | {
17 | protected $envFile;
18 | protected $data = [];
19 |
20 | public function __construct($envFile = RASPI_CONFIG_API. '/.env')
21 | {
22 | $this->envFile = $envFile;
23 | }
24 |
25 | public function load()
26 | {
27 | if (!file_exists($this->envFile)) {
28 | $this->createEnv();
29 | }
30 |
31 | if (file_exists($this->envFile)) {
32 | $this->data = parse_ini_file($this->envFile);
33 | foreach ($this->data as $key => $value) {
34 | if (!getenv($key)) {
35 | putenv("$key=$value");
36 | $_ENV[$key] = $value;
37 | }
38 | }
39 | } else {
40 | throw new \Exception(".env file '{$this->envFile}' not found.");
41 | }
42 | }
43 |
44 | public function set($key, $value)
45 | {
46 | $this->data[$key] = $value;
47 | putenv("$key=$value");
48 | $this->store($key, $value);
49 | }
50 |
51 | public function get($key)
52 | {
53 | return getenv($key);
54 | }
55 |
56 | public function getAll()
57 | {
58 | return $this->data;
59 | }
60 |
61 | public function unset($key)
62 | {
63 | unset($_ENV[$key]);
64 | return $this;
65 | }
66 |
67 | private function store($key, $value)
68 | {
69 | $content = file_get_contents($this->envFile);
70 | $content = preg_replace("/^$key=.*/m", "$key=$value", $content, 1, $count);
71 | if ($count === 0) {
72 | // if key doesn't exist, append it
73 | $content .= "$key=$value\n";
74 | }
75 | file_put_contents("/tmp/.env", $content);
76 | system('sudo mv /tmp/.env '.$this->envFile, $result);
77 | if ($result !== 0) {
78 | throw new \Exception("Unable to move .env file: ". $this->envFile);
79 | }
80 | }
81 |
82 | protected function createEnv()
83 | {
84 | exec('sudo touch '. escapeshellarg($this->envFile), $output, $result);
85 | if ($result !== 0) {
86 | throw new \Exception("Unable to create .env file: ". $this->envFile);
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/src/RaspAP/Exceptions/ExceptionHandler.php:
--------------------------------------------------------------------------------
1 |
8 | * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 | * @see
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace RaspAP\Exceptions;
15 |
16 | use RaspAP\Exceptions\HtmlErrorRenderer;
17 |
18 | class ExceptionHandler
19 | {
20 |
21 | public function __construct()
22 | {
23 | $this->setExceptionHandler();
24 | $this->setShutdownHandler();
25 | }
26 |
27 | public static function handleException($exception)
28 | {
29 | $errorMessage = (
30 | '[' . date('Y-m-d H:i:s') . '] ' .
31 | $exception->getMessage() . ' in ' .
32 | $exception->getFile() . ' on line ' .
33 | $exception->getLine() . PHP_EOL
34 | );
35 | // Log the exception
36 | error_log($errorMessage, 3, RASPI_ERROR_LOG);
37 |
38 | $renderer = new HtmlErrorRenderer();
39 | $renderer->render($exception);
40 | }
41 |
42 | public static function handleShutdown()
43 | {
44 | $error = error_get_last();
45 | if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
46 | $errorMessage = (
47 | '[' . date('Y-m-d H:i:s') . '] ' .
48 | $error['message'] . ' in ' .
49 | $error['file'] . ' on line ' .
50 | $error['line'] . PHP_EOL
51 | );
52 | error_log($errorMessage, 3, RASPI_ERROR_LOG);
53 |
54 | $renderer = new HtmlErrorRenderer();
55 | $renderer->render($exception);
56 | }
57 | }
58 |
59 | protected function setExceptionHandler()
60 | {
61 | set_exception_handler(array($this, 'handleException'));
62 | }
63 |
64 | protected function setShutdownHandler()
65 | {
66 | register_shutdown_function(array($this, 'handleShutdown'));
67 | }
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/RaspAP/Messages/StatusMessage.php:
--------------------------------------------------------------------------------
1 |
8 | * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 | */
10 |
11 | namespace RaspAP\Messages;
12 |
13 | class StatusMessage
14 | {
15 | public $messages = array();
16 |
17 | public function addMessage($message, $level = 'success', $dismissable = true)
18 | {
19 | $status = ''. _($message);
24 | if ($dismissable) {
25 | $status .= ' ';
26 | }
27 | $status .= '
';
28 |
29 | array_push($this->messages, $status);
30 | }
31 |
32 | public function showMessages($clear = true)
33 | {
34 | foreach ($this->messages as $message) {
35 | echo $message;
36 | }
37 | if ($clear) {
38 | $this->messages = array();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/RaspAP/Plugins/PluginInterface.php:
--------------------------------------------------------------------------------
1 |
8 | * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE
9 | * @see
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace RaspAP\Plugins;
15 |
16 | use RaspAP\UI\Sidebar;
17 |
18 | interface PluginInterface
19 | {
20 | /**
21 | * Initialize the plugin
22 | * @param Sidebar $sidebar Sidebar instance for adding items
23 | */
24 | public function initialize(Sidebar $sidebar): void;
25 |
26 | /**
27 | * Render a template within the plugin's template directory
28 | * @param string $templateName
29 | * @param array $__data
30 | * @return string
31 | */
32 | public function renderTemplate(string $templateName, array $__data = []): string;
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/templates/about/contributing.php:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/templates/about/general.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/templates/about/insiders.php:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/templates/adblock/custom.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
14 |
15 | IPv4 example: 0.0.0.0 badhost.com") ?>
16 |
17 | addn-hosts directive to the dnsmasq configuration.") ?>
18 |
19 |
20 |
21 |
22 |
23 |
24 | '.htmlspecialchars($adblock_custom_content, ENT_QUOTES).''; ?>
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/templates/adblock/general.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
19 |
20 |
21 |
22 |
:
23 |
24 |
:
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/templates/adblock/logging.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | '.htmlspecialchars($logdata, ENT_QUOTES).''; ?>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/templates/adblock/stats.php:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
--------------------------------------------------------------------------------
/templates/configure_client.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 | showMessages(); ?>
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
58 |
59 |
--------------------------------------------------------------------------------
/templates/dashboard.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | " name="ifup_wlan0" />
5 |
6 | " name="ifdown_wlan0" />
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
29 |
30 |
31 | showMessages(); ?>
32 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/templates/dashboard/data.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
20 |
--------------------------------------------------------------------------------
/templates/dhcp/clients.php:
--------------------------------------------------------------------------------
1 |
2 |
Client list
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/templates/dhcp/logging.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
dhcpcd and dnsmasq
activity.") ?>
5 |
6 |
7 | aria-describedby="log-dhcp-requests">
8 |
9 |
10 |
11 | aria-describedby="log-dhcp-queries">
12 |
13 | " />
14 |
15 |
16 |
17 |
18 | '.htmlspecialchars($logdata, ENT_QUOTES).'';
21 | } else {
22 | echo '';
23 | }
24 | ?>
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/templates/exception.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
Stack trace:
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/templates/hostapd/basic.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ">
22 |
23 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/templates/hostapd/logging.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
hostapd activity.") ?>
5 |
6 |
7 |
8 | />
9 |
10 | " />
11 |
12 |
13 |
14 |
15 | '.htmlspecialchars($logdata, ENT_QUOTES).'';
18 | } else {
19 | echo '';
20 | }
21 | ?>
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/templates/hostapd/security.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/templates/openvpn/configs.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | openvpn-client service.") ?>
8 |
9 |
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/templates/openvpn/logging.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
openvpn activity.") ?>
5 |
6 |
7 | aria-describedby="log-openvpn">
8 |
9 | " />
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/templates/provider.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | class="btn btn-outline btn-primary " name="SaveProviderSettings" value="" />
4 |
5 | class="btn btn-success " name="StartProviderVPN" value="" />
6 |
7 | class="btn btn-warning " name="StopProviderVPN" value="" />
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
28 |
29 | showMessages(); ?>
30 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/templates/provider/general.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | '. $item .'
';
27 | } ?>
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Save settings will connect to the selected country."); ?>
39 |
40 |
41 | Connect %s will connect to a recommended server."), $providerName); ?>
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/templates/provider/status.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
%s"), $providerVersion); ?>
6 |
%s connection status is displayed below."), strtolower($providerName)); ?>
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/templates/restapi.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | " />
4 |
5 | " />
6 |
7 | " />
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
28 |
29 | showMessages(); ?>
30 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/templates/restapi/general.php:
--------------------------------------------------------------------------------
1 |
25 |
26 |
--------------------------------------------------------------------------------
/templates/restapi/status.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
restapi.service status is displayed below."); ?>
5 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/templates/system/advanced.php:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
--------------------------------------------------------------------------------
/templates/system/language.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
" />
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/templates/system/plugins.php:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
--------------------------------------------------------------------------------
/templates/system/theme.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/templates/system/tools.php:
--------------------------------------------------------------------------------
1 |
2 |
38 |
39 |
--------------------------------------------------------------------------------
/templates/wg/logging.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
wg-quick debug log.") ?>
7 |
8 | aria-describedby="wgLogEnable">
9 |
10 |
11 | '.htmlspecialchars($wg_log, ENT_QUOTES).'';
12 | ?>
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/templates/wifi_stations.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
wpa_supplicant.") ?>
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/templates/wireguard.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | ">
4 |
5 | ">
6 |
7 | ">
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
28 |
29 | showMessages(); ?>
30 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------