Compare commits

...

537 Commits

Author SHA1 Message Date
KodeStar f820c0b4f6 Merge pull request #1388 from dfernandezdaw/2.x
Update Spanish translations
2024-11-05 10:56:55 +00:00
KodeStar 2b43760dc8 Merge pull request #1391 from linuxserver/bugfix/two_dots
Fix 2 dots that are visible on light backgrounds
2024-11-05 10:50:21 +00:00
KodeStar 8f360f97ef Merge branch '2.x' into bugfix/two_dots 2024-11-05 10:44:15 +00:00
KodeStar 014f054862 Merge pull request #1390 from linuxserver/feature/search_from_url
Search from URL fixed #1369
2024-11-05 10:42:59 +00:00
Chris Hunt 5ccb87cd7f Fix 2 dots that are visible on light backgrounds #1383 2024-11-05 10:42:05 +00:00
Chris Hunt 8ba8f0c867 Prettier fix 2024-11-05 10:33:12 +00:00
Chris Hunt c2a3368c7b Search from URL fixed #1369 2024-11-05 10:29:34 +00:00
KodeStar 395c775d4e Merge pull request #1387 from linuxserver/bugfix/search_category_tiles
Fix searching of tiles in category mode
2024-11-05 10:14:02 +00:00
KodeStar 1063d2cd09 Update app.php 2024-11-05 09:42:10 +00:00
David 18609fb3c2 Update Spanish translations 2024-11-04 21:18:04 +01:00
Chris Hunt b880333856 Fixes #1386 2024-11-04 10:30:24 +00:00
KodeStar 026bcf9e43 Merge pull request #1384 from linuxserver/feature/throttle_websitelookup
Throttle websitelookup's to 10 per minute to limit port scan effectiveness
2024-11-04 10:05:52 +00:00
Chris Hunt 837f5c49fa Throttle websitelookup's to 10 per minute to limit port scan effictiveness 2024-11-04 09:54:10 +00:00
KodeStar a4973869d4 Merge pull request #1372 from tremor021/2.x
Added Serbian translation
2024-11-04 09:38:23 +00:00
KodeStar 07ea22dd10 Merge pull request #1328 from goodactive/2.x
chore: fix some typos in comments
2024-11-04 09:25:06 +00:00
tremor021 6188b1d669 Added Serbian translation 2024-09-27 22:04:30 +02:00
goodactive 184e19abbc chore: fix some typos in comments
Signed-off-by: goodactive <goodactive@qq.com>
2024-04-19 18:00:20 +08:00
KodeStar f405cf2ddf Update validation.php
Fix missing comma in Japanese translation
2024-03-31 21:40:31 +01:00
KodeStar c16a4847f7 Update version number 2024-02-19 11:08:45 +00:00
KodeStar 9d0209c9df Merge pull request #1293 from KodeStar/2.x
Fixes to tags and show tags on application list
2024-02-19 11:08:18 +00:00
Chris Hunt 599035b3f8 Fix empty title when creating 2024-02-19 11:06:42 +00:00
Chris Hunt f3bc6ab618 Add tags to application list, and fix home dashboard tag 2024-02-19 10:58:19 +00:00
Chris Hunt 09e4bb8cad Fix required fields and default items and tags to pinned 2024-02-19 10:03:03 +00:00
Chris Hunt 4b8bf5156d Fix prettier complaints 2024-02-19 09:56:03 +00:00
KodeStar 809a997631 Merge pull request #1291 from KodeStar/2.x
Fix upload paths
2024-02-18 20:27:26 +00:00
Chris Hunt fb7f9de127 Fix upload paths 2024-02-18 20:26:20 +00:00
KodeStar 002bae3fb3 Merge pull request #1290 from KodeStar/feature/add_columns
Add alternate tag types
2024-02-18 18:35:43 +00:00
Chris Hunt b7c0fd29c6 Fix extra prettier complaints 2024-02-18 18:33:47 +00:00
Chris Hunt 70252b7a43 Fix prettier complaints 2024-02-18 18:26:34 +00:00
Chris Hunt d276bf8b1d Add alternate tag types 2024-02-18 18:16:46 +00:00
Chris Hunt a0726a43ad Updates 2024-02-18 09:06:37 +00:00
Chris Hunt 8fa870e8eb Initial commit 2024-02-18 09:06:03 +00:00
KodeStar d184427016 Merge pull request #1289 from linuxserver/revert-1288-2.x
Revert "Replace Mix with Vite"
2024-02-17 21:03:02 +00:00
KodeStar 36d1d55934 Revert "Replace Mix with Vite" 2024-02-17 21:02:45 +00:00
KodeStar 3a509fca47 Merge pull request #1288 from KodeStar/2.x
Replace Mix with Vite
2024-02-17 20:00:19 +00:00
KodeStar afc07ab9bc Update ci.yml 2024-02-17 19:59:33 +00:00
KodeStar 0de1e5bd25 Merge pull request #9 from KodeStar/shift-110402
Migrate from Laravel Mix to Vite
2024-02-17 19:57:42 +00:00
Chris Hunt 029def9d90 Update vite 2024-02-17 19:56:47 +00:00
Shift c6c9ec1d89 Ignore build assets 2024-02-17 19:03:26 +00:00
Shift 0f19e3c5de Add .vue extension to Vue imports 2024-02-17 19:03:25 +00:00
Shift f3a4ac3619 Rename ENV variables 2024-02-17 19:03:25 +00:00
Shift baf7131f20 Use ES modules 2024-02-17 19:03:24 +00:00
Shift 4430b21740 Remove webpack.mix.js 2024-02-17 19:03:24 +00:00
Shift 3a3cea437b Configure Vite 2024-02-17 19:03:23 +00:00
Shift aa5a6fce4c Update build scripts 2024-02-17 19:03:23 +00:00
Shift 8781dbc9f5 Add npm dependencies 2024-02-17 19:03:23 +00:00
KodeStar 23f3a9c343 Merge pull request #1283 from KodeStar/bugfix/unable_to_load_apps
Add missing classname
2024-02-17 17:06:44 +00:00
Chris Hunt 2899b7db61 Add missing 2024-02-17 17:05:06 +00:00
KodeStar e9bfd9a878 Merge pull request #1280 from KodeStar/bugfix/unable_to_load_apps
Unable to load apps after update to Laravel 10
2024-02-17 16:44:33 +00:00
Chris Hunt 5825858abc Unable to load apps after update to laravel 10 2024-02-17 16:42:26 +00:00
KodeStar 379ba34fe1 Merge pull request #1278 from KodeStar/bugfix/fix_language_dropdown
Fix languages dropdown
2024-02-17 15:27:55 +00:00
Chris Hunt a0e5111771 Fix languages 2024-02-17 15:13:43 +00:00
KodeStar c69961b200 Merge pull request #1277 from KodeStar/2.x
Update php version in CI tests
2024-02-17 10:21:13 +00:00
KodeStar 39f23103e4 Update ci.yml 2024-02-17 10:19:12 +00:00
KodeStar e7d581244c Update ci.yml 2024-02-17 10:14:55 +00:00
KodeStar 2fea82c21e Change to php 8.3 2024-02-17 10:08:50 +00:00
Chris Hunt 274894562c Update php version in CI tests 2024-02-17 10:04:01 +00:00
KodeStar 9fbb3457d1 Add Laravel 10 dependencies 2024-02-17 08:12:27 +00:00
KodeStar 70f212c502 Update readme.md 2024-02-16 21:44:27 +00:00
KodeStar 5e2c3a5f66 Merge pull request #1276 from KodeStar/2.x
Update Laravel from 8 to 10
2024-02-16 21:41:05 +00:00
Chris Hunt ffb5b03704 Update version 2024-02-16 21:38:25 +00:00
Chris Hunt d52ae0d3c3 Update dependencies 2024-02-16 21:36:54 +00:00
KodeStar 22d7a59e59 Merge pull request #8 from KodeStar/shift-110368
Laravel 10.x Shift
2024-02-16 21:30:12 +00:00
Shift f3a5be79dc Remove redundant typing from DocBlocks 2024-02-16 21:13:14 +00:00
Shift 3487f52a6b Add type hints from DocBlocks 2024-02-16 21:13:14 +00:00
Shift 2cb837e4b5 Add type hints for Laravel 10 2024-02-16 21:13:13 +00:00
Shift 8725493fcf Rename password_resets table 2024-02-16 21:13:11 +00:00
Shift e902b3a38a Bump Composer dependencies 2024-02-16 21:13:09 +00:00
Shift 854fb420c2 Default config files
In an effort to make upgrading the constantly changing config files
easier, Shift defaulted them and merged your true customizations -
where ENV variables may not be used.
2024-02-16 21:13:09 +00:00
Shift 5b4e14d886 Shift config files 2024-02-16 21:13:09 +00:00
Shift ef25ec4f69 Shift core files 2024-02-16 21:13:07 +00:00
Shift b943674881 Remove explicit call to register policies 2024-02-16 21:12:58 +00:00
Shift 3188a8f311 Convert string references to ::class
PHP 5.5.9 adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.
2024-02-16 21:12:53 +00:00
KodeStar 095aff86c2 Merge pull request #7 from KodeStar/shift-110367
Laravel 9.x Shift
2024-02-16 21:11:51 +00:00
Shift 018996526c Shift cleanup 2024-02-16 20:33:47 +00:00
Shift 1c73cf08de Adopt anonymous migrations 2024-02-16 20:33:46 +00:00
Shift 4bfcd643e6 Use <env> tags for configuration
`<env>` tags have a lower precedence than system environment variables making it easier to overwrite PHPUnit configuration values in additional environments, such a CI.

Review this blog post for more details on configuration precedence when testing Laravel: https://jasonmccreary.me/articles/laravel-testing-configuration-precedence/
2024-02-16 20:33:44 +00:00
Shift 04b8ede8db Bump Composer dependencies 2024-02-16 20:33:43 +00:00
Shift a6ae60270f Default config files
In an effort to make upgrading the constantly changing config files
easier, Shift defaulted them and merged your true customizations -
where ENV variables may not be used.
2024-02-16 20:33:43 +00:00
Shift ee3361d9c9 Shift config files 2024-02-16 20:33:43 +00:00
Shift 42b5a294d0 Adopt class based routes 2024-02-16 20:33:38 +00:00
Shift 14b89ac44d Convert route options to fluent methods
Laravel 8 adopts the tuple syntax for controller actions. Since the old options array is incompatible with this syntax, Shift converted them to use modern, fluent methods.
2024-02-16 20:33:37 +00:00
Shift ad86e54f37 Remove unnecessary $model property 2024-02-16 20:33:37 +00:00
Shift 0f4b336d82 Remove web.config 2024-02-16 20:33:37 +00:00
Shift 6423ccd075 Shift core files 2024-02-16 20:33:36 +00:00
Shift 72cd16afa1 Upgrade to Flysystem 3.0 2024-02-16 20:33:33 +00:00
Shift d41c4c8d4c Replace deprecated HEADER_X_FORWARDED_ALL constant 2024-02-16 20:33:33 +00:00
Shift 2b602ce66d Streamline $commands property 2024-02-16 20:33:32 +00:00
Shift aa72ce0a3f Shift registered middleware 2024-02-16 20:33:32 +00:00
Shift 825ff6a6c8 Move resources/lang folder 2024-02-16 20:33:30 +00:00
Shift be93195188 Convert string references to ::class
PHP 5.5.9 adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.
2024-02-16 20:33:27 +00:00
Shift 51b30e55cd Adopt short array syntax
Since PHP 5.4 the short array syntax `[]` may be used instead of `array()`.
2024-02-16 20:33:26 +00:00
KodeStar ecb668a8f3 Merge pull request #1155 from TheDen/add-search-application-item
add search via select2 for application dropdown
2024-02-12 19:44:23 +00:00
KodeStar 2e96b7bd09 Update app.php version 2023-11-11 15:04:44 +00:00
KodeStar 768e7a6576 Merge pull request #1222 from fyutins/2.x
Fix and add SVG support
2023-11-11 14:58:41 +00:00
Fyutins 431eafb2b6 Fix and add SVG support 2023-09-26 18:51:12 +02:00
Ian Jones d2184eef0a Update readme.md (#1186)
Spelling and Grammar, included a few apostrophes for correct plural form or possessive. 

Added Capitalization to proper nouns

Included a single colon for consistency to match the styling of  it's predecessor paragraph
2023-08-09 11:21:57 +02:00
Attila Kerekes fbd050d4e4 fix: validate icons to be images (#1173) 2023-06-06 12:08:47 +02:00
Attila Kerekes 5d67f570a9 fix: validate icons to be images (#1167) 2023-06-05 18:27:30 +02:00
Attila Kerekes 7d016cdaa6 fix: Remove mix from trianglify.js (#1166) 2023-05-26 13:36:07 +02:00
ullbergm 6e954a355d Add Trianglify (#1158) 2023-05-26 10:23:06 +02:00
KodeStar 60faccad27 Remove register route (#1163) 2023-05-20 21:56:34 +02:00
jatdung 1f5493ac98 fix sortable tooltip (#1130) 2023-05-16 16:42:17 +02:00
TheDen 427353bdfc add search via select2 for application dropdown 2023-04-29 18:25:02 +10:00
aptalca 9c117b7946 Merge pull request #1150 from linuxserver/2.x-project
handle issue-pr close and review submitted actions
2023-04-19 09:22:36 -04:00
aptalca c72fee9644 handle issue-pr close and review submitted actions 2023-04-14 15:31:46 -04:00
aptalca 0999bebcb4 Merge pull request #1147 from linuxserver/2.x-issues
add issue-pr workflows
2023-04-08 19:00:40 -04:00
aptalca 1c41e3d1ef add issue-pr workflows 2023-04-06 15:25:53 -04:00
Chris Hunt ed3cd79c92 Change minor version ready for next release 2023-03-09 16:17:32 +00:00
Chris Hunt 192002f898 Update minor version 2023-03-09 16:10:51 +00:00
jatdung 18f7306b2c Update Chinese language. (#1124) 2023-03-07 17:51:19 +01:00
jatdung e9754519be fix Request class error (#1126) 2023-03-07 12:32:58 +01:00
ShiftHackZ 1c276fbfc2 feat: Added Ukrainian translation (#1125) 2023-03-07 12:32:01 +01:00
jatdung cefe07d218 fix language setting only available in view (#1117) 2023-02-23 18:24:11 +01:00
jatdung cd4b522935 use sortablejs instead of jquery-ui (#1115) 2023-02-10 21:32:58 +01:00
angrystar170 1ad5603c3e Update Korean language. (#1116) 2023-02-10 21:30:38 +01:00
Attila Kerekes 302e04bb12 fix: Update jquery, jquery-ui (#1113) 2023-02-04 20:34:49 +01:00
Attila Kerekes 49dab6e72b fix: Add more error handling for app test (#1111) 2023-02-01 11:43:26 +01:00
Filipe F Moreira c5d0769afb Add BR translations (#1080) 2023-01-16 20:14:33 +01:00
KodeStar 4005894c16 Update app.php 2023-01-09 19:28:56 +00:00
Attila Kerekes a4022ce517 fix: Escape app title and tag title on list pages CVE-2022-47968 (#1088) 2023-01-05 20:31:15 +01:00
Attila Kerekes cd07d47445 fix: Add more verbose error when uploading background image (#1082) 2022-12-24 10:56:00 +01:00
Attila Kerekes df70dcc521 feat: Add tags as classes to items (#1079) 2022-12-19 14:40:38 +01:00
Attila Kerekes 9e6321e500 fix: Enable tag slug creation from CN characters (#1077) 2022-12-16 10:26:00 +01:00
KodeStar 0d9850c1c7 Merge pull request #1073 from linuxserver/fix/395
fix: Autologin forces logout
2022-12-15 23:38:36 +00:00
Attila Kerekes 4d3083886e fix: Autologin forces logout 2022-12-15 22:21:16 +01:00
KodeStar 52f59afe63 Merge pull request #1072 from linuxserver/fix/895
fix: Public access to front also applies to tags
2022-12-15 19:48:54 +00:00
Attila Kerekes aa886e4f77 fix: Public access to front also applies to tags 2022-12-15 20:17:08 +01:00
Attila Kerekes 3c9f361f5f chore: Add eslint github check (#1067) 2022-12-11 18:44:37 +01:00
Attila Kerekes 5eb1f55b82 chore: Add php code sniffer github check (#1066) 2022-12-11 11:58:58 +01:00
KodeStar d910f8e4f7 Merge pull request #1065 from linuxserver/feat/health
feat: Add health endpoint
2022-12-11 09:46:20 +00:00
Attila Kerekes 751b23a5e4 feat: Add health endpoint 2022-12-11 01:39:39 +01:00
Yusuke Arakawa a4fa490fb4 feat: Add Japanese language (#1064)
Co-authored-by: Yusuke Arakawa <nekolaboratory@users.noreply.github.com>
2022-12-09 23:43:23 +01:00
Yusuke Arakawa 662f6ac3eb chore: Sort the supported language list of readme.md (#1062) 2022-12-09 09:40:52 +01:00
Attila Kerekes 11257a272e feat: Introduce queue based live stat refresh (#1059) 2022-12-05 16:29:06 +01:00
Attila Kerekes 6b93f8ed5c test: Add item create test (#1058) 2022-12-05 16:28:18 +01:00
Attila Kerekes 8f9b2959b2 feat: Add basic import screen (#1056)
Co-authored-by: Chris Hunt <chris.hunt@kasmweb.com>
2022-12-04 22:12:54 +01:00
Attila Kerekes 45cc84c99c test: Add feature tests 2022-12-04 17:21:03 +00:00
Attila Kerekes 52620bc331 chore: Add laravel ide helper 2022-12-01 09:17:54 +00:00
Attila Kerekes bd76efc613 chore: Migrate route definition to Laravel 8 format 2022-11-29 21:34:11 +00:00
Attila Kerekes 6dead1c529 fix: Make supportedApps legacy interface compatible 2022-11-29 19:26:07 +00:00
Attila Kerekes bb5a078f35 feat: Add export import 2022-11-29 17:32:46 +00:00
Attila Kerekes 2ee5d07e48 fix: Make supportedapps compatible with legacy interface 2022-11-29 17:26:40 +00:00
Attila Kerekes d30edb6749 chore: Add eslint prettier phpcs config PSR2 2022-11-28 19:47:10 +00:00
Chris Hunt a53192beeb FIx: Blur onauxclick as well 2022-11-28 08:33:05 +00:00
Chris Hunt ef1ffe880d Update version to 2.5.4 2022-11-28 08:30:34 +00:00
KodeStar 877b31f947 Merge pull request #1041 from linuxserver/bug/links_opening_in_new_tab_keep_focus
Blur tiles after clicking on them
2022-11-26 17:02:45 +00:00
Chris Hunt 827088df76 Blur tiles after clicking on them 2022-11-26 14:48:54 +00:00
Attila Kerekes a12c1d559d fix: Use correct appTest argument type 2022-11-26 13:31:05 +00:00
KodeStar f0b60fc19a Merge pull request #1039 from linuxserver/fix/1038
fix: Enter should open search when not tile search is selected
2022-11-26 12:00:43 +00:00
Attila Kerekes 7c4619adb9 fix: Enter should open search when not tile search is selected 2022-11-26 12:22:12 +01:00
KodeStar aa49a5fb42 Fixes #371 Tagged items when pinning/unpinning (#1036) 2022-11-25 23:21:45 +00:00
Attila Jozsef Kerekes 7565bd4028 chore: Add php code sniffer and apply fixes 2022-11-25 23:05:58 +00:00
Chris Hunt 181b7564e8 Merge branch '2.x' of github.com:linuxserver/Heimdall into 2.x 2022-11-25 16:23:40 +00:00
Chris Hunt 0d3640b67a Fix asset links 2022-11-25 16:23:34 +00:00
Attila Kerekes 82b209d4b5 fix: Test enhanced app with apikey 2022-11-25 16:11:39 +00:00
Chris Hunt f576a82803 Fix: Change default logging to daily 2022-11-24 22:56:27 +00:00
Attila Kerekes bb07ba5964 feat: Add db connection example config 2022-11-24 14:28:16 +00:00
Attila Kerekes 9aaa900a3e fix: New package lock with node 18.12 2022-11-24 08:36:20 +00:00
KodeStar 07f07449b9 Update: Updated npm dependencies + using mix (#1026) 2022-11-23 19:39:00 +00:00
Attila Kerekes 2836dadf1a fix: Disable saerch submit when tile search is active 2022-11-23 18:12:21 +00:00
KodeStar 4a90fdf22d Merge pull request #1024 from KodeStar/2.x
Updated translations using lokalise.com
2022-11-23 15:11:54 +00:00
KodeStar 0de56e5876 Merge pull request #5 from KodeStar/lokalise-2022-11-23_16-08-41
Lokalise: Translations update
2022-11-23 15:10:37 +00:00
KodeStar d886b44c1e Updated translations using lokalise.com 2022-11-23 15:09:10 +00:00
Chris Hunt 898ee6915d Merge branch '2.x' of github.com:linuxserver/Heimdall into 2.x 2022-11-23 13:25:10 +00:00
Chris Hunt f6eae7f25f FIx: Use mix version rather than app version 2022-11-23 13:24:36 +00:00
KodeStar c1255280aa Merge pull request #1023 from linuxserver/feature/focus_and_sidebar_tooltips
Feature - focus and sidebar tooltips
2022-11-23 10:50:07 +00:00
Chris Hunt 5514d893f8 Fix: Add translations to sidebar tooltips 2022-11-23 10:19:27 +00:00
Chris Hunt c4d5ca43dd Feature: Add focus styling 2022-11-23 10:09:16 +00:00
Chris Hunt a90bcb1151 Fix: Move tooltips in from right 2022-11-23 09:42:33 +00:00
Chris Hunt ffc736ada6 Fix: Added nicer tooltips to sidebar 2022-11-23 09:29:52 +00:00
KodeStar 966027faf5 Merge pull request #1022 from keriati/feat/kbr 2022-11-23 08:41:21 +00:00
Attila Kerekes 1111bf72d6 feat: Add basic keyboard navigation 2022-11-22 22:53:07 +01:00
KodeStar cc6e47372e Merge pull request #1020 from keriati/feat/nopwsubmit
feat: Prevent password submission when password is not changed.
2022-11-22 17:06:16 +00:00
KodeStar 256160727c Merge pull request #1019 from keriati/feat/uniqueappupdate
feat: Make app update job unique
2022-11-22 17:05:28 +00:00
Attila Kerekes 0299ee6fa9 feat: Prevent password submission when password is not changed. 2022-11-22 17:52:10 +01:00
Attila Kerekes 8957a2f49f feat: Make app update job unique 2022-11-22 17:23:26 +01:00
KodeStar 756ab353f3 Merge pull request #1018 from keriati/feat/appupdatejob
feat: Move app update to background job
2022-11-22 09:12:16 +00:00
Attila Kerekes 76f0b84827 feat: Move app update to background job 2022-11-22 00:05:57 +01:00
KodeStar 68c8dbc33a Merge pull request #1017 from keriati/fix/appupdatereduce
fix: Throttle app updates when updating to new version.
2022-11-20 20:44:43 +00:00
Attila Kerekes b1e856ccfc fix: Throttle app updates when updating to new version. 2022-11-20 21:37:13 +01:00
KodeStar 44fb923b7f Merge pull request #1015 from keriati/feat/testpwinject
feat: Inject password from db during testing when editing enhanced apps
2022-11-19 19:53:32 +00:00
Attila Kerekes 8bad474808 feat: Inject password from db during testing when editing enhanced apps 2022-11-19 20:48:31 +01:00
KodeStar 9a80064a50 Merge pull request #1014 from KodeStar/2.x
Automated missing translation strings using lokalise.com
2022-11-19 13:22:28 +00:00
KodeStar e86c5e601d Merge pull request #4 from KodeStar/lokalise-2022-11-19_14-15-24
Lokalise: Translations update
2022-11-19 13:18:05 +00:00
KodeStar c4bf619be4 Updated translations using lokalise.com 2022-11-19 13:15:51 +00:00
KodeStar 4b29b476df Merge pull request #1012 from keriati/feat/appupdateon
feat: Trigger app update when new version is deployed
2022-11-19 12:41:09 +00:00
KodeStar 3a39809585 Merge pull request #1013 from keriati/fix/fri18n
fix: Add missing FR translations
2022-11-19 12:04:58 +00:00
Attila Kerekes 157b972ff5 feat: Trigger app update when new version is deployed 2022-11-18 17:35:55 +01:00
Attila Kerekes 71b15a5aed fix: Add missing FR translations 2022-11-18 17:12:50 +01:00
KodeStar b50bf716dc Merge pull request #1010 from keriati/feat/enhancedapppw
feat: Keep stored password when Enhanced App is updated
2022-11-17 21:20:16 +00:00
KodeStar 722d00df5f Merge pull request #1009 from keriati/feat/eslangupdate
feat: Add more ES translations. fixes #961
2022-11-17 21:18:49 +00:00
Attila Kerekes 54679ff9eb feat: Keep stored password when Enhanced App is updated 2022-11-17 21:13:10 +01:00
Attila Kerekes 4c7e56e6fe feat: Add more ES translations fixes #961 2022-11-17 21:05:50 +01:00
KodeStar 7b0ae66101 Merge pull request #1008 from keriati/fix/stoppollonerror
fix: Stop polling enhanced apps when api returns error
2022-11-17 17:30:26 +00:00
Attila Kerekes 48616e87bd fix: Stop polling enhanced apps when api returns error 2022-11-17 18:00:35 +01:00
Chris Hunt f9280cd4c0 Don't commit debugbar json files 2022-11-17 16:20:21 +00:00
KodeStar 3124a01011 Merge pull request #1007 from keriati/fix/userlang
fix: User language setting
2022-11-17 16:17:36 +00:00
Attila Kerekes ec27889086 fix: User language setting 2022-11-17 17:12:24 +01:00
KodeStar aba1f37b1c Merge pull request #1006 from smelikmartin/2.x
Added czech language resources
2022-11-17 09:51:01 +00:00
Martin Smelik 6565dfde07 Added czech language 2022-11-17 10:27:43 +01:00
KodeStar aa98c3505c Don't break if default search provider deleted from yaml
Fixes #904
2022-11-17 00:20:54 +00:00
KodeStar 15f5c3e5be Merge pull request #999 from keriati/fix/sessionexpired
fix: Expired session setCookie issue #379
2022-11-16 22:54:59 +00:00
Attila Kerekes fc2d153ded fix: Expired session setCookie issue #379 2022-11-16 23:53:34 +01:00
KodeStar 4a7690147e Update readme.md 2022-11-15 21:29:39 +00:00
KodeStar 7d32e6edb0 Merge pull request #975 from keriati/feat/langit
feat: add missing IT translations
2022-11-15 18:33:58 +00:00
Attila Kerekes 3d1fc80d64 feat: add missing IT translations 2022-11-15 14:07:12 +01:00
KodeStar 8b0700e9ef Merge pull request #974 from keriati/feat/langderu
Add missing DE and RU translations
2022-11-15 11:56:29 +00:00
Attila Kerekes cc241f1bd6 feat: Add DE and RU translations 2022-11-15 12:51:34 +01:00
Attila Kerekes 810ee03965 test: improve lang test debug output 2022-11-15 11:09:57 +01:00
KodeStar 7809abb376 Merge pull request #956 from keriati/chore/php7432
chore: set min php version 7.4.32
2022-11-14 23:49:15 +00:00
Attila Kerekes 2f3b7e52db chore: set min php version 7.4.32 2022-11-14 23:34:32 +01:00
KodeStar fdd5a78eb8 Merge pull request #955 from keriati/fix/php74dep
fix: install dependencies on php 7.4
2022-11-14 20:42:41 +00:00
Attila Jozsef Kerekes 98401f20a2 reinstall dependencies on php 7.4 2022-11-14 21:39:27 +01:00
Chris Hunt 30663e4d5e Change php version 2022-11-14 20:28:46 +00:00
Chris Hunt 8972a11c0a SImplify action 2022-11-14 19:43:43 +00:00
Chris Hunt bf349eec7a Merge branch '2.x' of github.com:linuxserver/Heimdall into 2.x 2022-11-14 19:42:43 +00:00
Chris Hunt cb314a4fd9 Change action to pull request 2022-11-14 19:42:37 +00:00
KodeStar 1a78c8077a Merge pull request #954 from keriati/feat/lang-support
feat: Dynamically add all languages to db
2022-11-14 19:38:26 +00:00
Attila Kerekes a3c75b2dd4 fix: Fall back to english only if intl is missing. 2022-11-14 20:35:25 +01:00
Chris Hunt ee77d09c58 Update dependencies 2022-11-14 19:35:16 +00:00
Chris Hunt 0966639699 Add actions 2022-11-14 19:22:46 +00:00
Attila Jozsef Kerekes 153bb0e91d chore: update readme.md with intl dependency 2022-11-14 20:02:51 +01:00
Attila Kerekes 0c7a60a5c7 fix: Add missing hungarian translations
Improve some existing translation keys
2022-11-14 19:56:10 +01:00
Attila Kerekes edb51e56f1 feat: Dynamically add all languages to db
Add unit test to find missing translations
2022-11-14 19:31:07 +01:00
KodeStar 99193a578e Merge pull request #818 from everaldofilho/language-pt-br
Change: added language pt in configuration, translated validation for pt-br
2022-11-14 15:07:45 +00:00
KodeStar 49b5d57e14 Delete SettingsSeeder.php 2022-11-14 15:07:22 +00:00
KodeStar 716d5a2f69 Merge pull request #880 from Yoshi315161/patch-1
Update German Translation
2022-11-14 15:05:07 +00:00
KodeStar 62340b07a9 Merge pull request #854 from bsciretti/2.x
Lombard translation
2022-11-14 15:04:36 +00:00
KodeStar 2312e8b648 Merge pull request #953 from keriati/refactor/ideafixes
refactor: apply auto fixes from idea
2022-11-14 14:53:14 +00:00
Attila Kerekes b390a719e9 refactor: apply auto fixes from idea 2022-11-14 14:48:38 +01:00
KodeStar d4f7ad842c Merge pull request #951 from keriati/fix/950-env-db
fix: change how database type is checked #950
2022-11-14 09:57:49 +00:00
Attila Kerekes 5c2501c1a7 fix: change how database type is checked #950 2022-11-14 10:24:58 +01:00
KodeStar 198ffd7665 Merge pull request #949 from keriati/fix/554-private-app-icon
fix: Don't write existing icons to disk
2022-11-13 23:22:54 +00:00
Attila Kerekes 7cf9d46eb3 fix: Don't write existing icons to disk 2022-11-14 00:08:09 +01:00
KodeStar 66dbbc835e Update app.php 2022-11-13 22:08:41 +00:00
KodeStar 178e46ca05 Merge pull request #947 from keriati/chore/laravel8
upgrade to laravel 8.0
2022-11-13 21:54:08 +00:00
Attila Kerekes 27f58c0866 upgrade to laravel 8.0 2022-11-13 21:18:38 +01:00
KodeStar 43f894b58d Merge pull request #946 from keriati/chore/db-setup
Remove sqlite db file creation when mysql or pgsql is used
2022-11-13 15:12:18 +00:00
Attila Kerekes b83f24c6f3 remove sqlite db file creation when mysql or pgsql is used 2022-11-13 11:34:58 +01:00
KodeStar b22fbdbad1 Merge pull request #944 from keriati/fix/429
fix: adjust home tag index for mysql/mariadb in database seeder
2022-11-11 20:30:54 +00:00
Attila Kerekes 6552a8c061 fix: adjust user id for postgresql in database seeder 2022-11-11 20:28:57 +00:00
Attila Kerekes bcd6f72b72 fix: adjust home tag index for mysql/mariadb in database seeder 2022-11-11 19:22:50 +00:00
KodeStar d4fe699029 Merge pull request #941 from keriati/fix/886
fix: disable tooltips while reordering items
2022-11-07 16:35:40 +00:00
Attila Kerekes db8fa38665 fix: disable tooltips while reordering items 2022-11-07 16:32:19 +00:00
KodeStar df41de3a9a Update app.php 2022-11-07 15:43:08 +00:00
KodeStar b3070bc8f9 Merge pull request #940 from keriati/fix/appmodelcheck
fix: Add check to appModel so websites can be added again
2022-11-05 08:18:54 +00:00
Attila Kerekes 487cdc483c fix: Add check to appModel so websites can be added again 2022-11-05 07:02:20 +00:00
KodeStar dcc0f90b23 Merge pull request #912 from eekdood/tag-hyperlink-fix
fix links in tag list
2022-10-31 17:46:03 +00:00
KodeStar 75014c8269 Merge pull request #937 from keriati/privateAppSupport
Improve Private App support
2022-10-31 10:32:55 +00:00
Attila Kerekes 386e4c788b feat: add remove option to registerapp 2022-10-28 14:48:04 +00:00
Attila Kerekes fe0109494e feat: support the listing of private apps 2022-10-28 13:21:25 +00:00
Attila Kerekes 6907695c5d feat: support the listing of private apps 2022-10-28 09:55:16 +00:00
Attila Kerekes 533af2dc49 feat: support the listing of private apps 2022-10-27 21:57:23 +00:00
Eric Fawcett 1ac5eb6d23 fix links 2022-09-20 17:47:38 +00:00
Yoshi315161 ca557fcaf1 Update app.php
Add missing translations
2022-07-21 12:34:22 +02:00
Kode e2ba89c80e Update dependencies 2022-06-29 13:20:08 +01:00
Kode bbae811cd8 Update app.php 2022-06-29 13:19:02 +01:00
Kode 589aa73a15 Update app.php 2022-06-29 13:17:08 +01:00
Kode fc023401f5 remove heimdall specific xsrf token as clearly not working 2022-06-29 13:13:00 +01:00
Brian Sciretti 1a4b6da3ea Update app.php 2022-05-28 02:08:43 +02:00
Brian Sciretti 02b82dc740 Update app.php 2022-05-28 02:06:25 +02:00
Brian Sciretti 4e5129ab8f Update app.php 2022-05-28 01:58:34 +02:00
Brian Sciretti 62d9b0cc76 Create app.php 2022-05-28 01:56:47 +02:00
KodeStar 02dfed0bc7 Merge pull request #823 from tomyvi/patch-2
Disable SSL checks on API calls
2022-04-12 11:56:20 +01:00
KodeStar 71d356935f Merge pull request #822 from tomyvi/patch-1
Disable SSL checks on API calls
2022-04-12 11:56:04 +01:00
KodeStar e53bae2c69 Update app.php 2022-04-12 11:51:47 +01:00
KodeStar 3117b9c483 Don't try to autoload file when checking if a class exists 2022-04-12 11:48:03 +01:00
tomyvi c5817c9b2e Disable SSL checks on API calls 2022-04-07 10:34:07 +02:00
tomyvi c403e8b2df Disable SSL checks on API calls 2022-04-07 10:33:31 +02:00
Everaldo da costa filho 1ca403cc6e change: added language pt in configuration, translated validation for pt-br 2022-04-02 21:20:17 -03:00
Kode 758c174141 Only getApp if app found 2022-04-02 15:19:55 +01:00
KodeStar 9bc9c48e06 Localhost doesn't like the certificate so ignore the warning 2022-03-30 13:14:35 +01:00
KodeStar 9a6dd623db add tag_id to fillable to try and fix #810 2022-03-30 13:14:05 +01:00
Kode d1c6001fae update app version 2022-03-26 19:01:11 +00:00
Kode 74196a2bfa Check if class exists before checking if it's a search provider 2022-03-26 18:59:49 +00:00
Kode 724110dad2 Run ProcessApps when database version is bumped 2022-03-25 15:35:05 +00:00
KodeStar 3a043e0165 Update app.php 2022-03-25 15:02:35 +00:00
KodeStar ac37c60e1f Merge pull request #800 from xiazeyu/baidu
added Baidu and sort order by alphabet
2022-03-25 15:01:22 +00:00
S4kura0ne 937e576520 move tiles to the first 2022-03-25 01:00:07 +08:00
KodeStar 9086e9bd75 Merge pull request #794 from xiazeyu/2.x
Latest Chinese translation combined #789 and #617
2022-03-24 13:21:07 +00:00
s4kura0ne 4c90d8c87e added Baidu and sort order by alphabet 2022-03-24 09:25:30 +08:00
s4kura0ne a4cceb3ae0 remove Baidu in searchprovides.yaml 2022-03-24 09:20:46 +08:00
s4kura0ne 90c21d700d merged old 'zh' translation, improved translation 2022-03-24 00:33:36 +08:00
s4kura0ne 15b1f3234b added translation for baidu 2022-03-24 00:23:08 +08:00
s4kura0ne a116345d60 remove unused translation 2022-03-24 00:21:47 +08:00
s4kura0ne 2b4e6d372c remove changes in outdated SettingsSeeder.php 2022-03-24 00:19:43 +08:00
s4kura0ne d370f2c3ee finished chinese translation 2022-03-23 10:09:18 +08:00
S4kura0ne ade09f3b1c Merge pull request #3 from xiazeyu/master
https://github.com/xiazeyu/Heimdall/pull/2
2022-03-23 09:31:58 +08:00
s4kura0ne 80aa120086 solved Russian readme conflict 2022-03-23 09:28:39 +08:00
S4kura0ne a5cbcaca03 Merge pull request #1 from anerg2046/2.x
Merge Chinese translate from anerg2046
2022-03-23 09:24:33 +08:00
Kode f2bfc26c5e Update app.php 2022-03-21 21:37:44 +00:00
Kode 9f0abb6f4d Strip out invalid characters from tile background 2022-03-21 21:37:14 +00:00
KodeStar 9ca2078e7d Add app version to asset url to bust cache 2022-03-21 06:42:59 +00:00
罗翀 9e4a06999b Chinese translate
add baidu search
2022-03-21 00:53:28 +08:00
KodeStar 8b72ff0a0d Merge pull request #787 from KodeStar/2.x
Laravel shift and update defaults
2022-03-19 15:07:11 +00:00
Kode 51ddaccc16 Update defaults 2022-03-19 15:04:26 +00:00
KodeStar 4ff1a4aec4 Merge pull request #1 from KodeStar/shift-58933
Upgrade Checker
2022-03-19 14:27:44 +00:00
KodeStar d5bd614cc6 Update Application.php 2022-03-19 14:05:01 +00:00
Shift 0f498eca75 Remove explicit deleted_at date cast 2022-03-19 13:54:34 +00:00
Shift 3dac9828c8 Convert to new helper methods
Laravel 5 added several new helper functions, including:

- `view()`
- `response()`
- `redirect()`
- `config()`
- `abort()`

Review the [helpers][1] documentation for more details.

[1]: https://laravel.com/docs/5.0/helpers
2022-03-19 13:54:34 +00:00
Shift 297c2bb30f Shift bindings
PHP 5.5.9+ adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.
2022-03-19 13:54:33 +00:00
Shift b1dc4d4a41 Apply Laravel coding style
Shift automatically applies the Laravel coding style - which uses the PSR-2 coding style as a base with some minor additions.

You may customize the adopted coding style by adding a [PHP CS Fixer][1] or [PHP CodeSniffer][2] config to your project root. Feel free to use [Shift's Laravel ruleset][3] to help you get started.

For more information on customizing the code style applied by Shift, [watch this short video][4].

[1]: https://github.com/FriendsOfPHP/PHP-CS-Fixer
[2]: https://github.com/squizlabs/PHP_CodeSniffer
[3]: https://gist.github.com/laravel-shift/cab527923ed2a109dda047b97d53c200
[4]: https://laravelshift.com/videos/shift-code-style
2022-03-19 13:54:32 +00:00
KodeStar 0fe6565346 Update app.php 2022-03-19 07:06:02 +00:00
KodeStar 85c68c1f46 Merge pull request #783 from xavier-GitHub76/2.x
Update app.php (French translations Fix) + version app (2.4.4)
2022-03-18 16:40:10 +00:00
Kode fc2191b8db Fix preview image 2022-03-18 16:36:05 +00:00
xavier-GitHub76 ee36a0cfae Update app.php
Update version app to 2.4.4
2022-03-18 14:32:15 +01:00
Kode a868a6cac1 Fix for creating tags not setting home dashboard as default 2022-03-18 10:10:00 +00:00
xavier-GitHub76 574756b236 Update app.php
French translate fix
2022-03-17 22:43:05 +01:00
Kode f9599079e5 Update app.php 2022-03-17 19:04:39 +00:00
Kode 10afffb71d Fix test button 2022-03-17 19:03:06 +00:00
KodeStar 79d53af339 Update app.php 2022-03-17 13:42:07 +00:00
KodeStar 8cc6a9cc63 Pull missing apps on update apps list 2022-03-17 13:41:50 +00:00
KodeStar 18001fbdd0 Get app regardless of if it's enhanced (might be a search provider) 2022-03-17 12:56:51 +00:00
KodeStar 398df75865 Merge branch '2.x' 2022-03-17 11:01:43 +00:00
KodeStar 41c2983312 Add warning about http being needed in url 2022-03-17 10:55:52 +00:00
KodeStar bd3b882b3a Squashed commit of the following:
commit e52bc9c6b2
Author: KodeStar <kodestar@gmail.com>
Date:   Thu Mar 17 10:23:15 2022 +0000

    Update supportedapps.json

commit a16233ee10
Author: KodeStar <kodestar@gmail.com>
Date:   Thu Mar 17 10:21:24 2022 +0000

    Fix for displaying svg icons correctly
2022-03-17 10:24:31 +00:00
KodeStar e52bc9c6b2 Update supportedapps.json 2022-03-17 10:23:15 +00:00
KodeStar a16233ee10 Fix for displaying svg icons correctly 2022-03-17 10:21:24 +00:00
Kode 5b177f1127 Merge branch '2.3' into 2.x 2022-03-16 20:16:04 +00:00
Kode f7633b6a5f Update mix-manifest.json 2022-03-16 20:15:22 +00:00
Kode d58e6cb560 Fix for #774 2022-03-16 20:13:16 +00:00
Kode 87fe9c1771 Move setLocale out of vie composer so it's available everywhere
Fixes #776
2022-03-16 20:07:43 +00:00
Kode 95d9e9edb9 Update app.php 2022-03-16 19:43:03 +00:00
Kode f7b2c51f9d Fix for old apps and icon selector 2022-03-16 19:41:01 +00:00
Kode 72c70e27f2 Remove refresh button for now as update code isn't ready yet 2022-03-16 18:39:47 +00:00
Kode becbe5ab96 More work on apps 2022-03-16 18:35:40 +00:00
Kode f5bce95808 Add missing lang string, fixed #773 2022-03-16 18:34:48 +00:00
KodeStar 1e2b807e05 Lots of work on apps 2022-03-16 15:49:44 +00:00
Kode ed3dbf2f14 More work on enhanced apps 2022-03-15 20:09:22 +00:00
Kode 1e35f83fed Changes to the tooltips 2022-03-15 19:08:10 +00:00
KodeStar 8499d100ff More work on apps 2022-03-15 18:19:01 +00:00
KodeStar bdeae6a722 Add missing files 2022-03-15 11:30:21 +00:00
Kode 4c63b66dbf Initial start of replacing apps list to use github generated list 2022-03-14 15:56:36 +00:00
Kode 371f52f92e Fixes #469 2022-03-14 12:25:20 +00:00
KodeStar 6daaf94974 Add details for search providers 2022-03-14 10:34:37 +00:00
Kode b8e5a22648 Update app.php 2022-03-14 07:56:41 +00:00
Kode e821edf01a Fix tags url
Fixes #763
2022-03-14 07:56:02 +00:00
Kode 188316df47 Fix search using incorrect value
fixes #764
2022-03-14 07:55:26 +00:00
Kode dd14ce8738 Update app.php 2022-03-13 19:31:30 +00:00
Kode d8e4053ce4 Merge branch 'master' of https://github.com/linuxserver/Heimdall 2022-03-13 19:30:27 +00:00
Kode f73b78f292 Add search providers as an editable yaml file + allow searching tiles 2022-03-13 19:30:24 +00:00
Kode 96ec1e0b08 Fixes #435 2022-03-13 16:13:36 +00:00
KodeStar 1904d9d910 Merge pull request #731 from linuxserver/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.11 to 4.17.21
2022-03-13 12:21:14 +00:00
KodeStar beb2851f4a Add noopener noreferrer to link 2022-03-13 09:20:58 +00:00
dependabot[bot] 645a0bc7fe Bump lodash from 4.17.11 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.21)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-13 08:53:35 +00:00
Kode ef73918098 Update jquery 2022-03-12 23:27:11 +00:00
Kode 06a23c70af Should fix #379 2022-03-12 13:09:50 +00:00
Kode 323a6e17c7 Update database.php 2022-03-12 13:09:03 +00:00
Kode 0ca07c9698 Update composer.json 2022-03-12 12:55:42 +00:00
Kode fbb21d2885 update redis config 2022-03-12 12:54:15 +00:00
Kode b6741c8ff0 Update readme.md 2022-03-12 11:55:06 +00:00
Kode 7fdca02af7 Allow numbers in apps 2022-03-12 10:45:37 +00:00
Kode 271100c25b Update app.php 2022-03-12 09:38:19 +00:00
KodeStar cfecce6100 Create SECURITY.md 2022-03-12 09:37:36 +00:00
Kode d71341df7a Update app.blade.php 2022-03-11 23:20:18 +00:00
Kode ac851f5a02 Update manifest.json 2022-03-11 23:15:55 +00:00
Kode d2a8b7af48 Update app.blade.php 2022-03-11 23:10:47 +00:00
Kode 4d7a86fbf7 Update .env.example 2022-03-11 22:53:25 +00:00
KodeStar 87a3af3dbf Merge pull request #654 from NoahNxT/master
Translation correction NL
2022-03-11 20:30:16 +00:00
KodeStar 79c76b9f50 Merge pull request #648 from angrystar170/master
Add korean language files
2022-03-11 20:29:52 +00:00
KodeStar d7742df802 Merge pull request #644 from OllieJC/custom
Add custom CSS and JS settings
2022-03-11 20:28:28 +00:00
KodeStar 736222e173 Merge pull request #614 from risiko79/fix/#507
FIX: #507 Tag URLs do not respect APP_URL
2022-03-11 20:23:34 +00:00
KodeStar 047ffb0b55 Merge pull request #581 from rtzra/feature/RussianLanguage
added Russian translation
2022-03-11 20:22:32 +00:00
KodeStar 505d17cf57 Merge pull request #561 from mattycourtney/master
Updated link to letsencrypt image to point to SWAG
2022-03-11 20:22:10 +00:00
KodeStar 71c2da160d Merge pull request #522 from bence192/patch-3
Create pagination.php
2022-03-11 20:17:58 +00:00
KodeStar 3487b9e479 Merge pull request #521 from bence192/patch-4
Create passwords.php
2022-03-11 20:17:39 +00:00
KodeStar 7cdf315d78 Merge pull request #512 from Babasile/master
Lang fr update
2022-03-11 20:17:18 +00:00
KodeStar a1812a962c Merge pull request #506 from Forceu/master
Added info about updating
2022-03-11 20:16:49 +00:00
KodeStar b97cab34b0 Merge pull request #492 from crazychatting/lang_de_update
Lang de update
2022-03-11 20:16:24 +00:00
KodeStar 3426450b3c Merge pull request #475 from e7jonas/patch-1
Fixed some spelling errors.
2022-03-11 20:15:53 +00:00
KodeStar 75804f4624 Merge pull request #457 from skay-zhang/patch-1
Creat new language
2022-03-11 20:15:21 +00:00
KodeStar 23f757e06f Merge pull request #454 from shaohao/Fix-password-issue
Update FormBuilder.php
2022-03-11 20:13:51 +00:00
KodeStar fabd704bab Merge pull request #520 from bence192/patch-1
Hungarian lang added
2022-03-11 20:13:01 +00:00
KodeStar c16fbae963 Merge pull request #523 from bence192/patch-2
Create auth.php
2022-03-11 20:12:45 +00:00
Kode 348759b9ad update logging 2022-03-11 19:38:08 +00:00
Kode d961aeb19b more urls with double slashes 2022-03-11 19:06:29 +00:00
Kode 987a9c03b0 fix for double slash on views 2022-03-11 19:03:03 +00:00
Kode d17fb04983 fix fa in pseudo classes 2022-03-11 10:40:47 +00:00
Kode b07918d751 changes to lv7 to maybe fix the symlink issues? 2022-03-11 10:07:42 +00:00
KodeStar f9a19fce91 Update to laravel 7 2022-03-10 11:54:29 +00:00
Noah Gillard 1b71e80d52 Translation correction NL 2022-02-08 22:58:07 +01:00
angrystar170 9fac11cb77 Update passwords.php 2022-01-23 23:30:53 +09:00
angrystar170 a94fb108fa Add korean language files 2022-01-23 23:24:54 +09:00
OllieJC f51893b2d6 Use pre for textarea settings 2022-01-22 13:30:50 +00:00
OllieJC a4b32dcafd Add textarea option 2022-01-18 22:59:40 +00:00
OllieJC 862f870303 Add settings.advanced/custom_css/custom_js 2022-01-18 22:42:53 +00:00
OllieJC 869cfd34ab Add custom CSS and JS options 2022-01-18 22:40:09 +00:00
OllieJC 9e67b7c72e Add custom_css and custom_js advance settings 2022-01-18 22:33:21 +00:00
risiko79 a5b7f10809 FIX: #507 Tag URLs do not respect APP_URL
see https://github.com/linuxserver/Heimdall/issues/507
2021-08-29 19:58:50 +02:00
Evgeny Cheremnykh 698665176c added Russian translation 2021-05-01 18:56:27 +03:00
Matty Courtney 1bd65222e4 Updated link to letsencrypt image to point to SWAG 2021-02-21 10:13:48 +08:00
KodeStar 61a5a1a8b0 Merge pull request #530 from jhaveDK/master
Danish translation
2020-12-07 12:39:14 +00:00
Jesper Have e51cdd7f7a Danish translation update 2020-12-06 18:58:05 +01:00
Jesper Have a626222ff3 Opdateret 2020-12-06 18:50:32 +01:00
Jesper Have af68a45a3d . 2020-12-06 18:40:37 +01:00
Jesper Have 7969df9344 Danish translation 2020-12-06 16:36:55 +01:00
bence192 67bc656325 Create passwords.php 2020-11-29 20:02:49 +01:00
bence192 b5baf0d606 Create pagination.php 2020-11-29 20:01:48 +01:00
bence192 32964e9045 Create auth.php 2020-11-29 20:00:29 +01:00
bence192 27a667675a Create app.php 2020-11-29 19:57:27 +01:00
Babasile 9a221f47bf Lang fr update 2020-10-24 11:19:57 +02:00
Marc Ole Bulling 8d2fbc5599 Added info about updating 2020-09-25 13:37:31 +02:00
Robin Loose 84ebe6587d added admin-account-needed in language 2020-08-03 00:45:36 +02:00
Robin Loose 89a71a18da updated and corrected language de 2020-08-01 02:12:01 +02:00
e7jonas 05dd7a090b Fixed some spelling errors. 2020-05-14 13:40:18 +01:00
KodeStar 3a9bdd2c43 Merge pull request #458 from AndyTempel/slovenian-translation
added Slovenian translation
2020-03-22 19:20:42 +00:00
AndrazKorenc 0292e9976e added Slovenian translation 2020-03-15 09:50:17 +01:00
sKai 365de9512f Creat new language
Creat simplified chinese , apply to china
2020-03-09 20:57:31 +08:00
Shao Hao e857023903 Update FormBuilder.php
Make she the value is passed to password input.
2020-03-03 14:11:51 +08:00
KodeStar c058e1a452 Merge pull request #446 from vinanrra/patch-1
Update app.php
2020-02-10 09:10:34 +00:00
vinanrra 7f42967b67 Update app.php
Added Jackett
2020-02-10 09:58:26 +01:00
KodeStar 994961de54 Merge pull request #438 from LeoShivas/patch-1
Make background image relative
2020-02-10 08:57:53 +00:00
KodeStar 049d20536c Merge pull request #397 from scottt732/search-app-fixes
Improved custom search handling
2020-02-10 08:56:29 +00:00
LeoShivas c9c8171a52 Make background image relative
I use Heimdall in a subfolder so that I access to it threw www.mydomain.com/heimdall/.
Custom background image doesn't load because Heimdall generate an absolute link (ie : www.mydomain.com/storage/backgrounds/mycustomimage.jpeg).
The link expected is www.mydomain.com/heimdall/storage/backgrounds/mycustomimage.jpeg.
To fix this, you have to make the path relative by replace in the code "/storage" by "storage" or "./storage".
2020-02-04 11:41:53 +01:00
KodeStar e7a6ac5a75 Merge pull request #412 from vincentbitter/remote_user-login
Fix auto-login using REMOTE_USER variable
2020-01-06 08:44:06 +00:00
KodeStar 3a372107ba Merge pull request #405 from vorpalhex/feature/#376/upload_icon_text
Update 'upload a file' to 'upload an icon'
2020-01-06 08:42:29 +00:00
KodeStar 493374de65 Merge pull request #404 from panigrc/feature-greek-translation
Greek translation
2020-01-06 08:40:49 +00:00
Vincent Bitter c43fc929f7 Do not try to login if user was not found 2019-11-15 21:30:10 +01:00
Vincent Bitter 895d5f2ebe Check if variables are empty since they always exist 2019-11-15 21:29:15 +01:00
VorpalHex cb4768e2cf Update 'upload a file' to 'upload an icon' 2019-10-12 18:11:23 -05:00
panigrc 6ca4bfb9ee Add greek language to the SettingsSeeder 2019-10-06 14:44:18 +02:00
panigrc 1f7de03d90 Add greek language files 2019-10-06 14:43:34 +02:00
Scott Holodak 861d287750 Improved custom search handling 2019-09-11 13:42:33 -04:00
KodeStar e2cc32fd0a Merge pull request #392 from auanasgheps/patch-1
Update Italian app.php
2019-08-29 14:58:19 +01:00
KodeStar 762df25c45 Merge pull request #393 from auanasgheps/patch-2
Create Italian auth.php
2019-08-29 14:56:39 +01:00
KodeStar 0b114e7dc1 Merge pull request #394 from auanasgheps/patch-3
Create pagination.php
2019-08-29 14:56:13 +01:00
Oliver Cervera 981876c43c Create pagination.php
File was missing.
Translated.
2019-08-28 18:56:46 +02:00
Oliver Cervera 7fe9c477e3 Create Italian auth.php
File was missing.
Translated.
2019-08-28 18:55:56 +02:00
Oliver Cervera 5b3a7f4e02 Update Italian app.php
- Added and translated missing strings
- Reworked existing strings
2019-08-28 18:53:15 +02:00
Kode 60e20c4023 fix route typo when restoring trash 2019-07-14 09:46:10 +01:00
Chris 9e1bb6c075 Update composer min php version 2019-07-11 15:01:07 +01:00
KodeStar 9c05d0d803 Update readme.md 2019-07-03 12:59:27 +01:00
KodeStar 3d1393c0b3 Merge pull request #370 from scodx/patch-1
some minor spanish translations fixes
2019-06-25 08:27:46 +01:00
KodeStar 9914fdb111 Merge pull request #373 from alxlaxv/patch-1
New translation for new SearchInterface
2019-06-25 08:27:07 +01:00
alxlaxv 9b24c9f1b5 New translation for new SearchInterface 2019-06-24 23:36:19 +02:00
Oscar Sánchez 81b8c646d2 some minor spanish translations fixes 2019-06-24 12:15:55 -05:00
Chris f734832e0f remove url() from around app link 2019-06-24 08:38:50 +01:00
KodeStar 1bde11b30b Update readme.md 2019-06-23 18:42:51 +01:00
Kode 9e80c3fe40 2.2.2 hasn't been released yet 2019-06-22 17:05:05 +01:00
Kode f272dd13ce Fix for tags not showing 2019-06-22 17:03:01 +01:00
Chris 9f26de89a4 add remember user and missing check icon 2019-06-19 12:11:55 +01:00
Chris e23964ebad set session and remember user when logged in via remote means 2019-06-19 12:01:17 +01:00
Chris d0584ac941 Update app version ready for next release 2019-06-19 11:49:17 +01:00
Chris 1410c41f48 Add REMOTE_USER auth 2019-06-19 11:32:41 +01:00
Chris 5f524563cf Merge branch 'master' of https://github.com/linuxserver/Heimdall 2019-06-18 13:41:06 +01:00
Chris 3d181623c3 fix small issue 2019-06-18 13:41:02 +01:00
KodeStar 1919dbfd96 Update readme.md 2019-06-18 13:22:14 +01:00
Chris 8e1615ac5f fix search tab behaviour and tag link in subfolder 2019-06-18 12:25:05 +01:00
Chris 7966f07fdb update scripts + add home dash as default tag 2019-06-18 11:51:07 +01:00
Chris ac8fe7012b remove false from routes 2019-06-18 10:51:51 +01:00
Chris 51d89dae82 Possible fix for folder based RP 2019-06-18 08:46:57 +01:00
KodeStar ef21ac0fe7 Merge pull request #359 from pahakalle/patch-1
Fix typo in Finnish translation
2019-06-13 19:10:04 +01:00
KodeStar 02697687cc Merge pull request #364 from linuxserver/hometags
Allow apps to be tagged to the homepage
2019-06-13 19:09:19 +01:00
Kode fd2f7f27a6 Make home tag translatable 2019-06-13 19:07:38 +01:00
Kode 21b1ef5e4b fix pin toggle and get homepage dash working 2019-06-13 18:59:01 +01:00
Chris e452d3b5f6 add seed 2019-06-13 15:57:54 +01:00
Chris 1419882455 initial 2019-06-13 15:40:26 +01:00
KodeStar d79202ed87 Update readme.md 2019-06-12 11:02:19 +01:00
KodeStar aa05c947a9 Remove url validation 2019-06-11 14:11:13 +01:00
Chris eb69ea05fa Update package-lock.json 2019-06-11 12:35:48 +01:00
Chris 244b0998f9 update bootstrap-sass 2019-06-11 12:34:28 +01:00
Chris 1f608b1c21 Update composer dependencies 2019-06-11 12:29:32 +01:00
Chris 7d6df3843b update node deps 2019-06-11 12:20:04 +01:00
Kalle Laine dd4b94ba71 Fix typo in Finnish translation 2019-06-11 14:18:08 +03:00
Chris edb9397a47 Add startpage back in 2019-06-11 12:02:18 +01:00
KodeStar 66815a8487 readd startpage 2019-06-11 11:45:13 +01:00
KodeStar 5ee19bceb6 Merge pull request #357 from Agurato/master
Add Qwant as search engine
2019-06-11 11:32:31 +01:00
KodeStar deba7d0279 Merge branch 'master' into master 2019-06-11 11:32:11 +01:00
KodeStar 38e93d33f1 remove startpage 2019-06-11 11:30:33 +01:00
KodeStar f182f305fc remove startpage 2019-06-11 11:30:17 +01:00
KodeStar 03c675ed57 remove startpage 2019-06-11 11:29:54 +01:00
KodeStar 3916b2d4dc remove startpage 2019-06-11 11:29:38 +01:00
KodeStar 698a7a9bbc remove startpage 2019-06-11 11:28:07 +01:00
KodeStar 9954d1b6bf Merge pull request #342 from dmbekker/master
Dutch Translation update
2019-06-11 11:04:52 +01:00
KodeStar a98b981efe Merge pull request #348 from Aerion/toggle-livestats-refresh-active-tab
turn off livestats update when the tab isn't active
2019-06-11 11:03:14 +01:00
KodeStar dd2ca62eaf Add private subnets to trusted proxies for reverse proxy use 2019-06-11 11:00:44 +01:00
Agurato dc2a42ad6d Add Qwant as search engine 2019-06-08 13:02:12 +02:00
Guillaume Taquet Gasperini b5b25458db turn off livestats update when the tab isn't active
Fixes #330: Turning off the updating when the tab isn't active

When the tab is not visible from the user, the livestats refresh are
stopped. As soon as its visibility changes (from visibilitychange
API), the livestats are refreshed as usual.

This will prevent unnecessary calls to the different services when the
tab is hidden from the user.
2019-05-20 21:58:03 +02:00
David ac4bbceb2f New Translations, Fixes for current translation
Added new translations

Minor language-issues fixed
- Changed 'Toepassing' to 'Applicatie' (Both Acronyms were used)
- Changed 'Reeks' to 'Tekenreeks'
2019-04-22 16:38:07 +02:00
Kode 4980bfab12 fix not protocol breaking adding for some reason 2019-03-30 23:10:00 +00:00
Chris 63e0d07d50 remove unused storeSearchProvider 2019-02-04 08:51:49 +00:00
Kode 2b76520e3a change version number and update lang value 2019-01-18 18:42:17 +00:00
Kode 6631b8a23b update dev npm deps 2019-01-18 18:37:51 +00:00
Kode 04d34017c1 Composer deps update 2019-01-18 18:33:28 +00:00
KodeStar 6dcbcb452e Merge pull request #316 from linuxserver/search-enhancements
Search enhancements
2019-01-18 18:27:19 +00:00
Kode 7c74b3bb13 update manifest 2019-01-18 18:26:07 +00:00
Kode b76a9ee118 Merge branch 'master' into search-enhancements 2019-01-18 18:25:00 +00:00
Kode 40da649b10 Changes to search 2019-01-18 18:21:44 +00:00
Chris cd64d762e7 additions to search 2019-01-18 15:21:50 +00:00
Chris b91c52820a replace fontawesome with js version 2019-01-18 14:07:17 +00:00
KodeStar 1204ffd306 Update app.php 2019-01-16 17:24:31 +00:00
Chris 978267dd14 Update Search.php 2019-01-16 15:00:42 +00:00
Chris f935fd94c6 initial work on seach changes 2019-01-16 14:47:32 +00:00
Chris fb2428e21b fixes #109 2019-01-16 14:20:33 +00:00
Chris e36a126c01 fixes #286 2019-01-16 12:02:38 +00:00
Chris b186978624 fixes #299 2019-01-16 11:39:39 +00:00
Chris 49773d7654 Fixes #302 2019-01-16 10:37:25 +00:00
Chris 53c03751a1 ignore supported apps folder 2019-01-16 10:35:55 +00:00
Chris 9d2908449a Merge branch 'master' of https://github.com/linuxserver/Heimdall 2019-01-15 15:27:29 +00:00
KodeStar caf92bcf6d check for gitignore in public storage and symlink if missing 2019-01-15 15:25:53 +00:00
KodeStar cbef469e02 Update AppServiceProvider.php 2019-01-15 15:23:10 +00:00
Chris a6bfc1d76c ignore .env 2019-01-15 14:27:19 +00:00
KodeStar 0446a74de9 Merge pull request #308 from openseabrus/master
Portuguese (PT-PT) translation.
2019-01-07 08:27:46 +00:00
KodeStar 1a14079b39 add APP_KEY 2019-01-04 14:00:15 +00:00
KodeStar d9c1919ddc Merge pull request #313 from linuxserver/Fix-default-appkey
Update .env.example
2019-01-04 11:52:07 +00:00
KodeStar f42ac0c5ba if .env is missing copy example and generate key 2019-01-04 10:38:07 +00:00
KodeStar c073929895 Delete .env 2019-01-04 10:36:04 +00:00
KodeStar 02df7844a4 Update .env.example 2019-01-04 10:34:12 +00:00
l1904l e43aba0111 Portuguese (PT-PT) translation. 2018-12-26 15:56:34 +00:00
Kode ac7446ffe6 update version 2018-11-14 18:14:23 +00:00
Kode e45d3ca6ec remove apps 2018-11-14 18:10:55 +00:00
Chris 603550a453 autofocus password 2018-11-13 12:38:19 +00:00
Kode 4463ef4a9a add right to livestats 2018-11-10 21:37:21 +00:00
Kode 49b8dc0079 Update version number 2018-11-10 18:05:19 +00:00
Kode ab83c3a551 Small changes
Copy icon if missing on new app add.
Change order of create symlink and load apps
2018-11-09 23:07:01 +00:00
Chris 98c6093674 Check url isn't missing when testing 2018-11-07 11:24:26 +00:00
Chris e1f51521bf Update version 2018-11-07 08:57:18 +00:00
Chris e85bc98dcc Fix ProcessJobs not working if folder is empty but table isn't 2018-11-07 08:54:00 +00:00
Chris 4ba52baa5c Remove old code from tags form 2018-11-06 15:44:09 +00:00
Chris a82077b4de Update version 2018-11-06 15:15:55 +00:00
Chris b8f04f3d11 Fix preview and config not retaining values 2018-11-06 14:52:45 +00:00
Chris e91f65f833 Ignore copy errors 2018-11-06 11:53:25 +00:00
Chris 575ab9be2d update version 2018-11-06 11:29:33 +00:00
Chris 64071bb60f Add migration and change path 2018-11-06 11:28:22 +00:00
Chris 44621a1a61 Change version + replace supported with icons 2018-11-06 09:48:03 +00:00
Chris c56043e1f9 Add default value to null rather than not set 2018-11-06 09:20:53 +00:00
Kode e8e4cbfd41 Change sort order for applist 2018-11-05 21:03:42 +00:00
Kode 4b2bbe0614 update version 2018-11-05 19:03:26 +00:00
Kode 9adfa14e62 fix light colour livestats 2018-11-05 19:02:19 +00:00
Kode 067f82b632 fix copy failing 2018-11-05 18:47:56 +00:00
Chris e24e7979be update version number 2018-11-05 15:28:17 +00:00
Chris c7c2b6e6f2 change location of icons so it's persistant 2018-11-05 15:27:29 +00:00
Chris 96798963d6 Update register app to allow all 2018-11-05 12:31:43 +00:00
Chris 75508a81ef Update version 2018-11-05 09:44:11 +00:00
Chris f7f4efadb7 Change html comment to php comment 2018-11-05 09:40:44 +00:00
Kode 4cc80b98db inconsequential update to try and fix broken build 2018-11-04 22:33:44 +00:00
16627 changed files with 1112936 additions and 550806 deletions
-31
View File
@@ -1,31 +0,0 @@
APP_NAME=Heimdall
APP_ENV=local
APP_KEY=base64:I206O8ibx+GQyRE7BeOxDobn04Mfmyyc5Ptzns/C0mY=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost
DB_CONNECTION=sqlite
DB_DATABASE=app.sqlite
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
+25 -10
View File
@@ -1,19 +1,24 @@
APP_NAME=Laravel
APP_NAME=Heimdall
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_DEBUG=false
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
LOG_CHANNEL=daily
DB_CONNECTION=sqlite
DB_DATABASE=app.sqlite
#DB_CONNECTION=<mysql | pgsql>
#DB_HOST=<hostname | ip>
#DB_PORT=<port number>
#DB_DATABASE=<database>
#DB_USERNAME=<user>
#DB_PASSWORD=<password>
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
@@ -22,14 +27,24 @@ REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+3
View File
@@ -0,0 +1,3 @@
huebee.js
jquery-ui.min.js
bootstrap.js
+13
View File
@@ -0,0 +1,13 @@
{
"extends": ["airbnb-base", "prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": ["error"]
},
"env": {
"browser": true
},
"globals": {
"$": true
}
}
@@ -0,0 +1,16 @@
name: Issue & PR Tracker
on:
issues:
types: [opened,reopened,labeled,unlabeled,closed]
pull_request_target:
types: [opened,reopened,review_requested,review_request_removed,labeled,unlabeled,closed]
pull_request_review:
types: [submitted,edited,dismissed]
jobs:
manage-project:
permissions:
issues: write
uses: linuxserver/github-workflows/.github/workflows/issue-pr-tracker.yml@v1
secrets: inherit
+13
View File
@@ -0,0 +1,13 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: '35 15 * * *'
workflow_dispatch:
jobs:
stale:
permissions:
issues: write
pull-requests: write
uses: linuxserver/github-workflows/.github/workflows/issues-cron.yml@v1
secrets: inherit
+59
View File
@@ -0,0 +1,59 @@
name: Tests (PHP)
on: [pull_request]
jobs:
tests:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php
with:
php-version: '8.3'
extensions: mbstring, dom, fileinfo, mysql, libxml, xml, xmlwriter, dom, tokenizer, filter, json, phar, pcre, openssl, pdo, intl, curl
- name: Cache composer dependencies
uses: actions/cache@v1
with:
path: vendor
key: composer-${{ hashFiles('composer.lock') }}
#- name: Run composer install
# run: composer install -n --prefer-dist
# env:
# APP_ENV: testing
- name: Prepare Laravel Application
run: |
cp .env.example .env
php artisan key:generate
- name: Cache yarn dependencies
uses: actions/cache@v1
with:
path: node_modules
key: yarn-${{ hashFiles('yarn.lock') }}
- name: Run yarn
run: yarn && yarn dev
- name: Run ESLint
run: yarn lint
- name: Run tests
run: php artisan test
env:
APP_ENV: testing
- name: Php code sniffer
run: ./vendor/bin/phpcs --config-set ignore_warnings_on_exit 1
- name: Upload artifacts
uses: actions/upload-artifact@master
if: failure()
with:
name: Logs
path: ./storage/logs
+4
View File
@@ -1,7 +1,9 @@
/app/SupportedApps
/node_modules
/public/hot
/public/storage
/storage/*.key
/storage/debugbar
/.idea
/.vagrant
Homestead.json
@@ -25,3 +27,5 @@ yarn-error.log
.Trashes
.VolumeIcon.icns
storage/app/public/avatars/*
.env
.phpunit.result.cache
+2339
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 2.3.x | :white_check_mark: |
| < 2.3 | :x: |
## Reporting a Vulnerability
You can report any vulnerabilities on our discord server by DM-ing a team member, or asking a team member to DM you.
https://discord.com/invite/YWrKVTn
+22155
View File
File diff suppressed because it is too large Load Diff
+160 -15
View File
@@ -2,54 +2,199 @@
namespace App;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* App\Application
*
* @property string $appid
* @property string $name
* @property string|null $sha
* @property string|null $icon
* @property string|null $website
* @property string|null $license
* @property string|null $description
* @property int $enhanced
* @property string $tile_background
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $class
* @method static Builder|Application newModelQuery()
* @method static Builder|Application newQuery()
* @method static Builder|Application query()
* @method static Builder|Application whereAppid($value)
* @method static Builder|Application whereClass($value)
* @method static Builder|Application whereCreatedAt($value)
* @method static Builder|Application whereDescription($value)
* @method static Builder|Application whereEnhanced($value)
* @method static Builder|Application whereIcon($value)
* @method static Builder|Application whereLicense($value)
* @method static Builder|Application whereName($value)
* @method static Builder|Application whereSha($value)
* @method static Builder|Application whereTileBackground($value)
* @method static Builder|Application whereUpdatedAt($value)
* @method static Builder|Application whereWebsite($value)
*/
class Application extends Model
{
/**
* @var bool
*/
public $incrementing = false;
/**
* @var string
*/
protected $primaryKey = 'appid';
//
/**
* @return mixed
*/
public function icon()
{
if (! file_exists(storage_path('app/public/'.$this->icon))) {
$img_src = app_path('SupportedApps/'.$this->name.'/'.str_replace('icons/', '', $this->icon));
$img_dest = storage_path('app/public/'.$this->icon);
//die("i: ".$img_src);
@copy($img_src, $img_dest);
}
return $this->icon;
}
public function iconView()
public function iconView(): string
{
return asset('storage/'.$this->icon);
}
public function defaultColour()
public function defaultColour(): string
{
// check if light or dark
if($this->tile_background == 'light') return '#fafbfc';
if ($this->tile_background == 'light') {
return '#fafbfc';
}
return '#161b1f';
}
public function class()
public function class(): string
{
$name = $this->name;
$name = preg_replace('/\PL/u', '', $name);
$name = preg_replace('/[^\p{L}\p{N}]/u', '', $name);
return \App\SupportedApps::class.'\\'.$name.'\\'.$name;
}
/**
* @param $name
*/
public static function classFromName($name): string
{
$name = preg_replace('/[^\p{L}\p{N}]/u', '', $name);
$class = \App\SupportedApps::class.'\\'.$name.'\\'.$name;
$class = '\App\SupportedApps\\'.$name.'\\'.$name;
return $class;
}
public static function applist()
public static function apps(): Collection
{
$json = json_decode(file_get_contents(storage_path('app/supportedapps.json'))) ?? [];
$apps = collect($json->apps);
return $apps->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE);
}
public static function autocomplete(): array
{
$apps = self::apps();
$list = [];
$all = self::orderBy('name')->get();
$list['null'] = 'None';
foreach($all as $app) {
$name = $app->name;
$name = preg_replace('/\PL/u', '', $name);
$list['\App\SupportedApps\\'.$name.'\\'.$name] = $app->name;
foreach ($apps as $app) {
$list[] = (object) [
'label' => $app->name,
'value' => $app->appid,
];
}
return $list;
}
/**
* @param $appid
* @return mixed|null
* @throws GuzzleException
*/
public static function getApp($appid)
{
Log::debug("Get app triggered for: $appid");
$localapp = self::where('appid', $appid)->first();
$app = self::single($appid);
$application = ($localapp) ? $localapp : new self;
// Files missing? || app not in db || old sha version
if (! file_exists(app_path('SupportedApps/'.className($app->name))) ||
! $localapp ||
$localapp->sha !== $app->sha
) {
$gotFiles = SupportedApps::getFiles($app);
if ($gotFiles) {
$app = SupportedApps::saveApp($app, $application);
}
}
return $app;
}
/**
* @param $appid
* @return mixed|null
*/
public static function single($appid)
{
$apps = self::apps();
$app = $apps->where('appid', $appid)->first();
if ($app === null) {
// Try in db for Private App
$appModel = self::where('appid', $appid)->first();
if ($appModel) {
$app = json_decode($appModel->toJson());
}
}
if ($app === null) {
return null;
}
$classname = preg_replace('/[^\p{L}\p{N}]/u', '', $app->name);
$app->class = \App\SupportedApps::class.'\\'.$classname.'\\'.$classname;
return $app;
}
public static function applist(): array
{
$list = [];
$list['null'] = 'None';
$apps = self::apps();
foreach ($apps as $app) {
$list[$app->appid] = $app->name;
}
// Check for private apps in the db
$appsListFromDB = self::all(['appid', 'name']);
foreach ($appsListFromDB as $app) {
// Already existing keys are overwritten,
// only private apps should be added at the end
$list[$app->appid] = $app->name;
}
return $list;
}
}
+60 -19
View File
@@ -2,9 +2,10 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Application;
use App\SupportedApps;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class RegisterApp extends Command
{
@@ -13,7 +14,7 @@ class RegisterApp extends Command
*
* @var string
*/
protected $signature = 'register:app {folder}';
protected $signature = 'register:app {folder} {--remove}';
/**
* The console command description.
@@ -34,28 +35,68 @@ class RegisterApp extends Command
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
public function handle(): void
{
$folder = $this->argument('folder');
$json = app_path('SupportedApps/'.$folder.'/app.json');
if(file_exists($json)) {
$app = json_decode(file_get_contents($json));
$exists = Application::find($app->appid);
if($exists) {
$this->error('This app is already registered');
exit;
if ($folder == 'all') {
$apps = scandir(app_path('SupportedApps'));
foreach ($apps as $folder) {
if ($folder == '.' || $folder == '..') {
continue;
}
$this->addApp($folder);
}
// Doesn't exist so add it
SupportedApps::saveApp($app, new Application);
$this->info("Application Added - ".$app->name." - ".$app->appid);
} else {
$this->error('Could not find '.$json);
$this->addApp($folder, $this->option('remove'));
}
}
/**
* @param $folder
*/
public function addApp($folder, bool $remove = false): void
{
$json = app_path('SupportedApps/'.$folder.'/app.json');
if (!file_exists($json)) {
$this->error('Could not find ' . $json);
return;
}
$app = json_decode(file_get_contents($json));
if (!isset($app->appid)) {
$this->error('No App ID for - ' . $folder);
return;
}
$exists = Application::find($app->appid);
if ($exists) {
if ($remove) {
$exists->delete();
$this->info('Application Removed - ' . $app->name . ' - ' . $app->appid);
return;
}
$this->error('Application already registered - ' . $exists->name . ' - ' . $exists->appid);
return;
}
// Doesn't exist so add it
SupportedApps::saveApp($app, new Application);
$this->saveIcon($folder, $app->icon);
$this->info('Application Added - ' . $app->name . ' - ' . $app->appid);
}
/**
* @param $appFolder
* @param $icon
*/
private function saveIcon($appFolder, $icon): void
{
$iconPath = app_path('SupportedApps/' . $appFolder . '/' . $icon);
$contents = file_get_contents($iconPath);
Storage::disk('public')->put('icons/'.$icon, $contents);
}
}
+2 -16
View File
@@ -7,22 +7,10 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')
// ->hourly();
@@ -30,10 +18,8 @@ class Kernel extends ConsoleKernel
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
protected function commands(): void
{
$this->load(__DIR__.'/Commands');
+6 -6
View File
@@ -1,12 +1,12 @@
<?php namespace App;
<?php
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
namespace App;
interface EnhancedApps
{
public function test();
public function livestats();
public function url($endpoint);
}
public function livestats();
public function url($endpoint);
}
+9 -32
View File
@@ -2,52 +2,29 @@
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
* The list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $exception
* @return void
* Register the exception handling callbacks for the application.
*/
public function report(Exception $exception)
public function register(): void
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
$this->reportable(function (Throwable $e) {
//
});
}
}
+114 -20
View File
@@ -1,44 +1,138 @@
<?php
function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afterunit = '')
use Illuminate\Support\Str;
/**
* @param $bytes
* @param bool $is_drive_size
* @param string $beforeunit
* @param string $afterunit
* @return string
*/
function format_bytes($bytes, bool $is_drive_size = true, string $beforeunit = '', string $afterunit = ''): string
{
$btype = ($is_drive_size === true) ? 1000 : 1024;
$labels = array('B','KB','MB','GB','TB');
for($x = 0; $bytes >= $btype && $x < (count($labels) - 1); $bytes /= $btype, $x++); // use 1000 rather than 1024 to simulate HD size not real size
if($labels[$x] == "TB") return(round($bytes, 3).$beforeunit.$labels[$x].$afterunit);
elseif($labels[$x] == "GB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
elseif($labels[$x] == "MB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
else return(round($bytes, 0).$beforeunit.$labels[$x].$afterunit);
$btype = ($is_drive_size === true) ? 1000 : 1024;
$labels = ['B', 'KB', 'MB', 'GB', 'TB'];
// use 1000 rather than 1024 to simulate HD size not real size
for ($x = 0; $bytes >= $btype && $x < (count($labels) - 1); $bytes /= $btype, $x++) ;
if ($labels[$x] == 'TB') {
return round($bytes, 3) . $beforeunit . $labels[$x] . $afterunit;
} elseif ($labels[$x] == 'GB') {
return round($bytes, 2) . $beforeunit . $labels[$x] . $afterunit;
} elseif ($labels[$x] == 'MB') {
return round($bytes, 2) . $beforeunit . $labels[$x] . $afterunit;
} else {
return round($bytes, 0) . $beforeunit . $labels[$x] . $afterunit;
}
}
function get_brightness($hex) {
/**
* @param $title
* @param string $separator
* @param string $language
* @return string
*/
function str_slug($title, string $separator = '-', string $language = 'en'): string
{
return Str::slug($title, $separator, $language);
}
if (!function_exists('str_is')) {
/**
* Determine if a given string matches a given pattern.
*
* @param string|array $pattern
* @param string $value
* @return bool
*
* @deprecated Str::is() should be used directly instead. Will be removed in Laravel 6.0.
*/
function str_is($pattern, string $value): bool
{
return Str::is($pattern, $value);
}
}
/**
* @param $hex
* @return float|int
*/
function get_brightness($hex)
{
// returns brightness value from 0 to 255
// strip off any leading #
$hex = str_replace('#', '', $hex);
if(strlen($hex) == 3) {
$hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
// $hex = str_replace('#', '', $hex);
$hex = preg_replace("/[^0-9A-Fa-f]/", '', $hex);
if (strlen($hex) == 3) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
$c_r = hexdec(substr($hex, 0, 2));
$c_g = hexdec(substr($hex, 2, 2));
$c_b = hexdec(substr($hex, 4, 2));
return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;
}
function title_color($hex)
/**
* @param $hex
* @return string
*/
function title_color($hex): string
{
if(get_brightness($hex) > 130) {
if (get_brightness($hex) > 130) {
return ' black';
} else {
return ' white';
}
}
function className($name)
/**
* @return string
*/
function getLinkTargetAttribute(): string
{
$name = preg_replace('/\PL/u', '', $name);
return $name;
$target = \App\Setting::fetch('window_target');
if ($target === 'current') {
return '';
} else {
return ' target="' . $target . '"';
}
}
/**
* @param $name
* @return array|string|string[]|null
*/
function className($name)
{
return preg_replace('/[^\p{L}\p{N}]/u', '', $name);
}
/**
* @param string $file
* @param string $extension
* @return bool
*/
function isImage(string $file, string $extension): bool
{
$allowedExtensions = ['jpg', 'jpeg', 'png', 'bmp', 'gif', 'svg', 'webp'];
if (!in_array($extension, $allowedExtensions)) {
return false;
}
$tempFileName = @tempnam("/tmp", "image-check-");
$handle = fopen($tempFileName, "w");
fwrite($handle, $file);
fclose($handle);
if ($extension == 'svg') {
return 'image/svg+xml' === mime_content_type($tempFileName);
}
$size = @getimagesize($tempFileName);
return is_array($size) && str_starts_with($size['mime'], 'image');
}
+38 -16
View File
@@ -3,12 +3,18 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\URL;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;
class LoginController extends Controller
{
@@ -30,7 +36,7 @@ class LoginController extends Controller
*
* @var string
*/
protected $redirectTo = '/';
protected string $redirectTo = '/';
/**
* Create a new controller instance.
@@ -40,10 +46,10 @@ class LoginController extends Controller
public function __construct()
{
Session::put('backUrl', URL::previous());
$this->middleware('guest')->except('logout');
$this->middleware('guest')->except(['logout','autologin']);
}
public function username()
public function username(): string
{
return 'username';
}
@@ -51,15 +57,13 @@ class LoginController extends Controller
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Illuminate\Validation\ValidationException
* @throws ValidationException
*/
public function login(Request $request)
public function login(Request $request): Response
{
$current_user = User::currentUser();
$request->merge(['username' => $current_user->username]);
$request->merge(['username' => $current_user->username, 'remember' => true]);
//die(print_r($request->all()));
$this->validateLogin($request);
@@ -88,39 +92,57 @@ class LoginController extends Controller
{
}
public function setUser(User $user)
public function setUser(User $user): RedirectResponse
{
Auth::logout();
session(['current_user' => $user]);
return redirect()->route('dash');
}
public function autologin($uuid)
/**
* @param $uuid
*/
public function autologin($uuid): RedirectResponse
{
Auth::logout();
$user = User::where('autologin', $uuid)->first();
Auth::login($user);
if (!$user) {
return redirect()->route('dash');
}
Auth::login($user, true);
session(['current_user' => $user]);
return redirect()->route('dash');
}
/**
* Show the application's login form.
*
* @return \Illuminate\Http\Response
* @return Application|Factory|View
*/
public function showLoginForm()
public function showLoginForm(): \Illuminate\View\View
{
return view('auth.login');
}
protected function authenticated(Request $request, $user)
/**
* @param $user
*/
protected function authenticated(Request $request, $user): RedirectResponse
{
return back();
}
/**
* @return mixed|string
*/
public function redirectTo()
{
return Session::get('url.intended') ? Session::get('url.intended') : $this->redirectTo;
}
}
@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
@@ -27,7 +27,7 @@ class RegisterController extends Controller
*
* @var string
*/
protected $redirectTo = '/';
protected string $redirectTo = '/';
/**
* Create a new controller instance.
@@ -41,11 +41,8 @@ class RegisterController extends Controller
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
protected function validator(array $data): \Illuminate\Contracts\Validation\Validator
{
return Validator::make($data, [
'name' => 'required|string|max:255',
@@ -56,11 +53,8 @@ class RegisterController extends Controller
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
protected function create(array $data): User
{
return User::create([
'name' => $data['name'],
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
*
* @var string
*/
protected $redirectTo = '/';
protected string $redirectTo = '/';
/**
* Create a new controller instance.
+4 -7
View File
@@ -2,16 +2,14 @@
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\Auth;
use App\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
use AuthorizesRequests, ValidatesRequests;
protected $user;
@@ -22,7 +20,6 @@ class Controller extends BaseController
//print_r($this->user);
return $next($request);
});
}
public function user()
+51
View File
@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers;
use App\Item;
use App\User;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\RateLimiter;
class HealthController extends Controller
{
private static function getUsers(): int
{
return User::count();
}
private static function getItems(): int
{
return Item::select('id')
->where('deleted_at', null)
->where('type', '0')
->count();
}
/**
* Handle the incoming request.
*
* @return JsonResponse|Response
* @throws BindingResolutionException
*/
public function __invoke(Request $request)
{
$REQUESTS_MAX_PER_MIN = 30;
$STATUS_TOO_MANY_REQUESTS = 429;
if (RateLimiter::remaining('health', $REQUESTS_MAX_PER_MIN) < 1) {
return response()->make('Too many attempts.', $STATUS_TOO_MANY_REQUESTS);
}
RateLimiter::hit('health');
return response()->json([
'status' => 'ok',
'items' => self::getItems(),
'users' => self::getUsers(),
]);
}
}
+3 -4
View File
@@ -2,7 +2,7 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
class HomeController extends Controller
{
@@ -13,15 +13,14 @@ class HomeController extends Controller
*/
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
public function index(): RedirectResponse
{
return redirect()->route('dash');
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\View\View;
class ImportController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
$this->middleware('allowed');
}
/**
* Handle the incoming request.
*/
public function __invoke(Request $request): View
{
return view('items.import');
}
}
+309 -167
View File
@@ -2,44 +2,81 @@
namespace App\Http\Controllers;
use Artisan;
use App\Application;
use App\Item;
use App\Setting;
use App\User;
use GrahamCampbell\GitHub\Facades\GitHub;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\SupportedApps;
use App\Jobs\ProcessApps;
use App\User;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\ServerException;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Validation\ValidationException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
class ItemController extends Controller
{
public function __construct()
{
parent::__construct();
$this->middleware('allowed');
}
/**
/**
* Display a listing of the resource on the dashboard.
*
* @return \Illuminate\Http\Response
*/
public function dash()
public function dash(): View
{
$data['apps'] = Item::doesntHave('parents')->pinned()->orderBy('order', 'asc')->get();
$data['all_apps'] = Item::doesntHave('parents')->get();
$treat_tags_as = \App\Setting::fetch('treat_tags_as');
$data["treat_tags_as"] = $treat_tags_as;
if ($treat_tags_as == 'categories') {
$data['categories'] = Item::whereHas('children')->with('children', function ($query) {
$query->pinned()->orderBy('order', 'asc');
})->pinned()->orderBy('order', 'asc')->get();
} elseif ($treat_tags_as == 'tags') {
$data['apps'] = Item::with('parents')->where('type', 0)->pinned()->orderBy('order', 'asc')->get();
$data['all_apps'] = Item::where('type', 0)->orderBy('order', 'asc')->get();
$data['taglist'] = Item::where('id', 0)->orWhere(function($query) {
$query->where('type', 1)->pinned();
})->orderBy('order', 'asc')->get();
} else {
$data['apps'] = Item::whereHas('parents', function ($query) {
$query->where('id', 0);
})->orWhere('type', 1)->pinned()->orderBy('order', 'asc')->get();
$data['all_apps'] = Item::whereHas('parents', function ($query) {
$query->where('id', 0);
})->orWhere(function ($query) {
$query->where('type', 1)->whereNot('id', 0);
})->orderBy('order', 'asc')->get();
}
//$data['all_apps'] = Item::doesntHave('parents')->get();
// die(print_r($data));
return view('welcome', $data);
}
/**
/**
* Set order on the dashboard.
*
* @return \Illuminate\Http\Response
* @return void
*/
public function setOrder(Request $request)
{
$order = array_filter($request->input('order'));
foreach($order as $o => $id) {
foreach ($order as $o => $id) {
$item = Item::find($id);
$item->order = $o;
$item->save();
@@ -49,216 +86,252 @@ class ItemController extends Controller
/**
* Pin item on the dashboard.
*
* @return \Illuminate\Http\Response
* @param $id
*/
public function pin($id)
public function pin($id): RedirectResponse
{
$item = Item::findOrFail($id);
$item->pinned = true;
$item->save();
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route);
}
/**
/**
* Unpin item on the dashboard.
*
* @return \Illuminate\Http\Response
* @param $id
*/
public function unpin($id)
public function unpin($id): RedirectResponse
{
$item = Item::findOrFail($id);
$item->pinned = false;
$item->save();
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route);
}
/**
/**
* Unpin item on the dashboard.
*
* @return \Illuminate\Http\Response
* @return RedirectResponse|View
*/
public function pinToggle($id, $ajax=false)
public function pinToggle($id, $ajax = false, $tag = false)
{
$item = Item::findOrFail($id);
$new = ((bool)$item->pinned === true) ? false : true;
$new = !(((bool)$item->pinned === true));
$item->pinned = $new;
$item->save();
if($ajax) {
$data['apps'] = Item::pinned()->get();
if ($ajax) {
$item = Item::whereId($tag)->first();
$data['apps'] = new Collection;
if ((int)$tag === 0) {
$tags = Item::where('type', 1)->pinned()->orderBy('order', 'asc')->get();
$data['apps'] = $data['apps']->merge($tags);
}
$apps = $item->children()->pinned()->orderBy('order', 'asc')->get();
$data['apps'] = $data['apps']->merge($apps);
$data['ajax'] = true;
return view('sortable', $data);
} else {
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route);
}
}
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
public function index(Request $request): View
{
$trash = (bool)$request->input('trash');
$data['apps'] = Item::ofType('item')->orderBy('title', 'asc')->get();
$data['trash'] = Item::ofType('item')->onlyTrashed()->get();
if($trash) {
if ($trash) {
return view('items.trash', $data);
} else {
return view('items.list', $data);
}
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
public function create(): View
{
//
$data['tags'] = Item::ofType('tag')->orderBy('title', 'asc')->pluck('title', 'id');
$data['current_tags'] = [];
return view('items.create', $data);
$data['tags']->prepend(__('app.dashboard'), 0);
$data['current_tags'] = '0';
return view('items.create', $data);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* Show the form for editing the specified resource.
*/
public function store(Request $request)
public function edit(int $id): View
{
//
// Get the item
$item = Item::find($id);
if ($item->appid === null && $item->class !== null) { // old apps won't have an app id so set it
$app = Application::where('class', $item->class)->first();
if ($app) {
$item->appid = $app->appid;
}
}
$data['item'] = $item;
$data['tags'] = Item::ofType('tag')->orderBy('title', 'asc')->pluck('title', 'id');
$data['tags']->prepend(__('app.dashboard'), 0);
$data['current_tags'] = $data['item']->tags();
//$data['current_tags'] = $data['item']->parent;
//die(print_r($data['current_tags']));
// show the edit form and pass the nerd
return view('items.edit', $data);
}
/**
* @param null $id
* @throws ValidationException
*/
public static function storelogic(Request $request, $id = null): Item
{
$application = Application::single($request->input('appid'));
$validatedData = $request->validate([
'title' => 'required|max:255',
'url' => 'required|url',
'url' => 'required',
'file' => 'image'
]);
if($request->hasFile('file')) {
$path = $request->file('file')->store('icons');
if ($request->hasFile('file')) {
$path = $request->file('file')->store('icons', 'public');
$request->merge([
'icon' => $path
'icon' => $path,
]);
} elseif (strpos($request->input('icon'), 'http') === 0) {
$options = [
"ssl" => [
"verify_peer" => false,
"verify_peer_name" => false,
],
];
$file = $request->input('icon');
$path_parts = pathinfo($file);
$extension = $path_parts['extension'];
$contents = file_get_contents($request->input('icon'), false, stream_context_create($options));
if (!isImage($contents, $extension)) {
throw ValidationException::withMessages(['file' => 'Icon must be an image.']);
}
$path = 'icons/' . ($application ? $application->icon : md5($contents) . '.' . $extension);
// Private apps could have here duplicated icons folder
if (strpos($path, 'icons/icons/') !== false) {
$path = str_replace('icons/icons/', 'icons/', $path);
}
if (!Storage::disk('public')->exists($path)) {
Storage::disk('public')->put($path, $contents);
}
$request->merge([
'icon' => $path,
]);
}
$config = Item::checkConfig($request->input('config'));
// Don't overwrite the stored password if it wasn't submitted when updating the item
if ($id !== null && strpos($config, '"password":null') !== false) {
$storedItem = Item::find($id);
$storedConfigObject = json_decode($storedItem->getAttribute('description'));
$configObject = json_decode($config);
$configObject->password = $storedConfigObject->password;
$config = json_encode($configObject);
}
$current_user = User::currentUser();
$request->merge([
'description' => $config,
'user_id' => $current_user->id
'user_id' => $current_user->getId(),
]);
if($request->input('class') === 'null') {
if ($request->input('appid') === 'null') {
$request->merge([
'class' => null,
]);
} else {
$request->merge([
'class' => Application::classFromName($application->name),
]);
}
//die(print_r($request->input('config')));
$item = Item::create($request->all());
if ($id === null) {
$item = Item::create($request->all());
} else {
$item = Item::find($id);
$item->update($request->all());
}
$item->parents()->sync($request->tags);
return $item;
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
self::storelogic($request);
$route = route('dash', []);
$route = route('dash', [], false);
return redirect($route)
->with('success', __('app.alert.success.item_created'));
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
public function show(int $id): void
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
// Get the item
$data['item'] = Item::find($id);
$data['tags'] = Item::ofType('tag')->orderBy('title', 'asc')->pluck('title', 'id');
$data['current_tags'] = $data['item']->parents;
// show the edit form and pass the nerd
return view('items.edit', $data);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
public function update(Request $request, int $id): RedirectResponse
{
$validatedData = $request->validate([
'title' => 'required|max:255',
'url' => 'required|url',
]);
//die(print_r($request->all()));
if($request->hasFile('file')) {
$path = $request->file('file')->store('icons');
$request->merge([
'icon' => $path
]);
}
$config = Item::checkConfig($request->input('config'));
$current_user = User::currentUser();
$request->merge([
'description' => $config,
'user_id' => $current_user->id
]);
self::storelogic($request, $id);
$route = route('dash', []);
if($request->input('class') === 'null') {
$request->merge([
'class' => null,
]);
}
$item = Item::find($id);
$item->update($request->all());
$item->parents()->sync($request->tags);
$route = route('dash', [], false);
return redirect($route)
->with('success',__('app.alert.success.item_updated'));
->with('success', __('app.alert.success.item_updated'));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
public function destroy(Request $request, int $id): RedirectResponse
{
//
$force = (bool)$request->input('force');
if($force) {
if ($force) {
Item::withTrashed()
->where('id', $id)
->forceDelete();
@@ -266,98 +339,167 @@ class ItemController extends Controller
Item::find($id)->delete();
}
$route = route('items.index', [], false);
return redirect($route)
->with('success',__('app.alert.success.item_deleted'));
$route = route('items.index', []);
return redirect($route)
->with('success', __('app.alert.success.item_deleted'));
}
/**
* Restore the specified resource from soft deletion.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function restore($id)
public function restore(int $id): RedirectResponse
{
//
Item::withTrashed()
->where('id', $id)
->restore();
$route = route('items.inded', [], false);
->where('id', $id)
->restore();
$route = route('items.index', []);
return redirect($route)
->with('success',__('app.alert.success.item_restored'));
->with('success', __('app.alert.success.item_restored'));
}
/**
* Return details for supported apps
*
* @return Json
* @throws GuzzleException
*/
public function appload(Request $request)
public function appload(Request $request): ?string
{
$output = [];
$appname = $request->input('app');
//die($appname);
$appid = $request->input('app');
$app_details = Application::where('name', $appname)->firstOrFail();
$appclass = $app_details->class();
$app = new $appclass;
// basic details
$output['icon'] = $app_details->icon();
$output['name'] = $app_details->name;
$output['iconview'] = $app_details->iconView();
$output['colour'] = $app_details->defaultColour();
$output['class'] = $appclass;
// live details
if($app instanceof \App\EnhancedApps) {
$output['config'] = className($app_details->name).'.config';
} else {
$output['config'] = null;
if ($appid === 'null') {
return null;
}
$output['config'] = null;
$output['custom'] = null;
$app = Application::single($appid);
$output = (array)$app;
$appdetails = Application::getApp($appid);
if ((bool)$app->enhanced === true) {
// if(!isset($app->config)) { // class based config
$output['custom'] = className($appdetails->name) . '.config';
// }
}
$output['colour'] = ($app->tile_background == 'light') ? '#fafbfc' : '#161b1f';
if (strpos($app->icon, '://') !== false) {
$output['iconview'] = $app->icon;
} elseif (strpos($app->icon, 'icons/') !== false) {
// Private apps have the icon locally
$output['iconview'] = URL::to('/') . '/storage/' . $app->icon;
$output['icon'] = str_replace('icons/', '', $output['icon']);
} else {
$output['iconview'] = config('app.appsource') . 'icons/' . $app->icon;
}
return json_encode($output);
}
/**
* @return void
*/
public function testConfig(Request $request)
{
$data = $request->input('data');
//$url = $data[array_search('url', array_column($data, 'name'))]['value'];
$app = $data['type'];
$single = Application::single($data['type']);
$app = $single->class;
// If password is not resubmitted fill it from the database when in edit mode
if (array_key_exists('password', $data) &&
$data['password'] === null &&
array_key_exists('id', $data)
) {
$item = Item::find($data['id']);
if ($item) {
$itemConfig = $item->getConfig();
$data['password'] = $itemConfig->password;
}
}
$app_details = new $app();
$app_details->config = (object)$data;
$app_details->test();
}
/**
* @param $url
* @param array|bool $overridevars
* @throws GuzzleException
*/
public function execute($url, array $attrs = [], $overridevars = false): ?ResponseInterface
{
$vars = ($overridevars !== false) ?
$overridevars : [
'http_errors' => false,
'timeout' => 15,
'connect_timeout' => 15,
'verify' => false,
];
$client = new Client($vars);
$method = 'GET';
try {
return $client->request($method, $url, $attrs);
} catch (ConnectException $e) {
Log::error('Connection refused');
Log::debug($e->getMessage());
} catch (ServerException $e) {
Log::debug($e->getMessage());
}
return null;
}
/**
* @param $url
* @throws GuzzleException
*/
public function websitelookup($url): StreamInterface
{
$url = base64_decode($url);
$data = $this->execute($url);
return $data->getBody();
}
/**
* @param $id
* @return void
*/
public function getStats($id)
{
$item = Item::find($id);
$config = $item->getconfig();
if(isset($item->class)) {
if (isset($item->class)) {
$application = new $item->class;
$application->config = $config;
echo $application->livestats();
}
}
public function checkAppList()
/**
* @return \Illuminate\Contracts\Foundation\Application|RedirectResponse|Redirector
*/
public function checkAppList(): RedirectResponse
{
ProcessApps::dispatch();
$route = route('items.index');
return redirect($route)
->with('success', __('app.alert.success.updating'));
}
}
@@ -0,0 +1,93 @@
<?php
namespace App\Http\Controllers;
use App\Item;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Collection;
class ItemRestController extends Controller
{
public function __construct()
{
parent::__construct();
$this->middleware('allowed');
}
/**
* Display a listing of the resource.
*/
public function index(): Collection
{
$columns = [
'title',
'colour',
'url',
'description',
'appid',
'appdescription',
];
return Item::select($columns)
->where('deleted_at', null)
->where('type', '0')
->orderBy('order', 'asc')
->get();
}
/**
* Show the form for creating a new resource.
*
* @return void
*/
public function create()
{
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): object
{
$item = ItemController::storelogic($request);
if ($item) {
return (object) ['status' => 'OK'];
}
return (object) ['status' => 'FAILED'];
}
/**
* Display the specified resource.
*/
public function show(Item $item): Response
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Item $item): Response
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Item $item): Response
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Item $item): Response
{
//
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers;
use App\Search;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
class SearchController extends Controller
{
/**
* @return Application|RedirectResponse|Redirector|mixed|void
*/
public function index(Request $request)
{
$requestprovider = $request->input('provider');
$query = $request->input('q');
$provider = Search::providerDetails($requestprovider);
if ($provider->type == 'standard') {
return redirect($provider->url.'?'.$provider->query.'='.urlencode($query));
} elseif ($provider->type == 'external') {
$class = new $provider->class;
//print_r($provider);
return $class->getResults($query, $provider);
}
//print_r($provider);
}
}
+59 -52
View File
@@ -2,24 +2,22 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Setting;
use App\SettingGroup;
use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class SettingsController extends Controller
{
public function __construct()
{
parent::__construct();
$this->middleware('allowed');
}
/**
* @return \Illuminate\View\View
*/
public function index()
public function index(): View
{
$settings = SettingGroup::with([
'settings',
@@ -31,89 +29,98 @@ class SettingsController extends Controller
}
/**
* @param int $id
*
* @return \Illuminate\Http\RedirectResponse
* @return RedirectResponse|View
*/
public function edit($id)
public function edit(int $id)
{
$setting = Setting::find($id);
//die("s: ".$setting->label);
if((bool)$setting->system === true) return abort(404);
if ((bool) $setting->system === true) {
return abort(404);
}
if (!is_null($setting)) {
if (! is_null($setting)) {
return view('settings.edit')->with([
'setting' => $setting,
]);
} else {
$route = route('settings.list', [], false);
return redirect($route)
$route = route('settings.list', []);
return redirect($route)
->with([
'error' => __('app.alert.error.not_exist'),
'errors' => collect([__('app.alert.error.not_exist')]),
]);
}
}
/**
* @param int $id
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request, $id)
public function update(Request $request, int $id): RedirectResponse
{
$setting = Setting::find($id);
$user = $this->user();
$route = route('settings.index', []);
if (!is_null($setting)) {
$data = Setting::getInput();
try {
if (is_null($setting)) {
throw new Exception('not_exists');
}
if ($setting->type == 'image') {
if ($setting->type === 'image') {
$validatedData = $request->validate([
'value' => 'image'
]);
if($request->hasFile('value')) {
$path = $request->file('value')->store('backgrounds');
$setting_value = $path;
if (!$request->hasFile('value')) {
throw new \Exception(
'file_too_big'
);
}
$path = $request->file('value')->store('backgrounds', 'public');
if ($path === null) {
throw new \Exception('file_not_stored');
}
$setting_value = $path;
} else {
$data = Setting::getInput($request);
$setting_value = $data->value;
}
$user->settings()->detach($setting->id);
$user->settings()->save($setting, ['uservalue' => $setting_value]);
$route = route('settings.index', [], false);
return redirect($route)
->with([
'success' => __('app.alert.success.setting_updated'),
]);
} else {
$route = route('settings.index', [], false);
return redirect($route)
->with([
'error' => __('app.alert.error.not_exist'),
]);
return redirect($route)
->with([
'success' => __('app.alert.success.setting_updated'),
]);
} catch (Exception $e) {
return redirect($route)
->with([
'errors' => collect([__('app.alert.error.'.$e->getMessage())]),
]);
}
}
/**
* @param int $id
*
* @return \Illuminate\Http\RedirectResponse
*/
public function clear($id)
public function clear(int $id): RedirectResponse
{
$user = $this->user();
$setting = Setting::find($id);
if((bool)$setting->system !== true) {
if ((bool) $setting->system !== true) {
$user->settings()->detach($setting->id);
$user->settings()->save($setting, ['uservalue' => '']);
}
$route = route('settings.index', [], false);
return redirect($route)
$route = route('settings.index', []);
return redirect($route)
->with([
'success' => __('app.alert.success.setting_updated'),
]);
}
public function search(Request $request)
{
}
}
+65 -62
View File
@@ -2,10 +2,13 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Item;
use App\User;
use DB;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class TagController extends Controller
{
@@ -13,18 +16,19 @@ class TagController extends Controller
{
$this->middleware('allowed');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
* @return Application|Factory|View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\View\View
{
$trash = (bool)$request->input('trash');
$trash = (bool) $request->input('trash');
$data['apps'] = Item::ofType('tag')->orderBy('title', 'asc')->get();
$data['trash'] = Item::ofType('tag')->onlyTrashed()->get();
if($trash) {
$data['apps'] = Item::ofType('tag')->where('id', '>', 0)->orderBy('title', 'asc')->get();
$data['trash'] = Item::ofType('tag')->where('id', '>', 0)->onlyTrashed()->get();
if ($trash) {
return view('tags.trash', $data);
} else {
return view('tags.list', $data);
@@ -34,34 +38,33 @@ class TagController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return Application|Factory|View
*/
public function create()
public function create(): \Illuminate\View\View
{
$data = [];
return view('tags.create', $data);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
public function store(Request $request): RedirectResponse
{
$validatedData = $request->validate([
'title' => 'required|max:255',
'file' => 'image'
]);
if($request->hasFile('file')) {
$path = $request->file('file')->store('icons');
if ($request->hasFile('file')) {
$path = $request->file('file')->store('icons', 'public');
$request->merge([
'icon' => $path
'icon' => $path,
]);
}
$slug = str_slug($request->title, '-');
$slug = str_slug($request->title, '-', 'en_US');
$current_user = User::currentUser();
@@ -69,12 +72,13 @@ class TagController extends Controller
$request->merge([
'type' => '1',
'url' => $slug,
'user_id' => $current_user->id
'user_id' => $current_user->getId(),
]);
//die(print_r($request->all()));
Item::create($request->all());
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route)
->with('success', __('app.alert.success.tag_created'));
}
@@ -82,120 +86,119 @@ class TagController extends Controller
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
* @param $slug
*/
public function show($slug)
public function show($slug): View
{
$item = Item::whereUrl($slug)->first();
//print_r($item);
$data['apps'] = $item->children()->pinned()->orderBy('order', 'asc')->get();
$data['tag'] = $item->id;
$data['all_apps'] = $item->children;
return view('welcome', $data);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
public function edit(int $id): View
{
// Get the item
$item = Item::find($id);
// show the edit form and pass the nerd
return view('tags.edit')
->with('item', $item);
->with('item', $item);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
public function update(Request $request, int $id): RedirectResponse
{
$validatedData = $request->validate([
'title' => 'required|max:255',
'file' => 'image'
]);
if($request->hasFile('file')) {
$path = $request->file('file')->store('icons');
if ($request->hasFile('file')) {
$path = $request->file('file')->store('icons', 'public');
$request->merge([
'icon' => $path
'icon' => $path,
]);
}
$slug = str_slug($request->title, '-');
$slug = str_slug($request->title, '-', 'en_US');
// set item type to tag
$request->merge([
'url' => $slug
'url' => $slug,
]);
Item::find($id)->update($request->all());
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route)
->with('success',__('app.alert.success.tag_updated'));
->with('success', __('app.alert.success.tag_updated'));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
public function destroy(Request $request, int $id): RedirectResponse
{
//
$force = (bool)$request->input('force');
if($force) {
$force = (bool) $request->input('force');
if ($force) {
Item::withTrashed()
->where('id', $id)
->forceDelete();
} else {
Item::find($id)->delete();
}
$route = route('tags.index', [], false);
$route = route('tags.index', []);
return redirect($route)
->with('success',__('app.alert.success.item_deleted'));
->with('success', __('app.alert.success.item_deleted'));
}
/**
* Restore the specified resource from soft deletion.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function restore($id)
public function restore(int $id): RedirectResponse
{
//
Item::withTrashed()
->where('id', $id)
->restore();
$route = route('tags.index', [], false);
->restore();
$route = route('tags.index', []);
return redirect($route)
->with('success',__('app.alert.success.item_restored'));
->with('success', __('app.alert.success.item_restored'));
}
public function add($tag, $item)
/**
* Add item to tag
*
* @param $tag
* @param $item
* @return int 1|0
*/
public function add($tag, $item): int
{
$output = 0;
$tag = Item::find($tag);
$item = Item::find($item);
if($tag && $item) {
if ($tag && $item) {
// only add items, not cats
if((int)$item->type === 0) {
if ((int) $item->type === 0) {
$tag->children()->attach($item);
return 1;
}
}
return $output;
}
return 0;
}
}
+47 -58
View File
@@ -2,62 +2,60 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Str;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class UserController extends Controller
{
public function __construct()
{
parent::__construct();
$this->middleware('allowed')->except(['selectUser']);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
public function index(): View
{
$data['users'] = User::all();
return view('users.index', $data);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
public function create(): View
{
$data = [];
return view('users.create', $data);
}
public function selectUser()
public function selectUser(): \Illuminate\View\View
{
Auth::logout();
$data['users'] = User::all();
return view('userselect', $data);
return view('userselect', $data);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
public function store(Request $request): RedirectResponse
{
$validatedData = $request->validate([
'username' => 'required|max:255|unique:users',
'email' => 'required|email',
'password' => 'nullable|confirmed',
'password_confirmation' => 'nullable'
'password_confirmation' => 'nullable',
'file' => 'image'
]);
$user = new User;
$user->username = $request->input('username');
@@ -65,111 +63,102 @@ class UserController extends Controller
$user->public_front = $request->input('public_front');
$password = $request->input('password');
if(!empty($password)) {
if (! empty($password)) {
$user->password = bcrypt($password);
}
if($request->hasFile('file')) {
$path = $request->file('file')->store('avatars');
if ($request->hasFile('file')) {
$path = $request->file('file')->store('avatars', 'public');
$user->avatar = $path;
}
if ((bool)$request->input('autologin_allow') === true) {
$user->autologin = (string)Str::uuid();
if ((bool) $request->input('autologin_allow') === true) {
$user->autologin = (string) Str::uuid();
}
$user->save();
$route = route('dash', [], false);
$route = route('dash', []);
return redirect($route)
->with('success',__('app.alert.success.user_updated'));
->with('success', __('app.alert.success.user_updated'));
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
public function show(int $id): void
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit(User $user)
public function edit(User $user): View
{
$data['user'] = $user;
return view('users.edit', $data);
return view('users.edit', $data);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, User $user)
public function update(Request $request, User $user): RedirectResponse
{
$validatedData = $request->validate([
'username' => 'required|max:255|unique:users,username,'.$user->id,
'email' => 'required|email',
'password' => 'nullable|confirmed',
'password_confirmation' => 'nullable'
'password_confirmation' => 'nullable',
'file' => 'image'
]);
//die(print_r($request->all()));
//die(print_r($request->all()));
$user->username = $request->input('username');
$user->email = $request->input('email');
$user->public_front = $request->input('public_front');
$password = $request->input('password');
if(!empty($password)) {
if (! empty($password)) {
$user->password = bcrypt($password);
} elseif($password == 'null') {
} elseif ($password == 'null') {
$user->password = null;
}
if($request->hasFile('file')) {
$path = $request->file('file')->store('avatars');
if ($request->hasFile('file')) {
$path = $request->file('file')->store('avatars', 'public');
$user->avatar = $path;
}
if ((bool)$request->input('autologin_allow') === true) {
$user->autologin = (is_null($user->autologin)) ? (string)Str::uuid() : $user->autologin;
if ((bool) $request->input('autologin_allow') === true) {
$user->autologin = (is_null($user->autologin)) ? (string) Str::uuid() : $user->autologin;
} else {
$user->autologin = null;
}
$user->save();
$route = route('dash', [], false);
return redirect($route)
->with('success',__('app.alert.success.user_updated'));
$route = route('dash', []);
return redirect($route)
->with('success', __('app.alert.success.user_updated'));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
* @return RedirectResponse | void
*/
public function destroy(User $user)
public function destroy(User $user): RedirectResponse
{
if($user->id !== 1) {
if ($user->id !== 1) {
$user->delete();
$route = route('dash', [], false);
return redirect($route)
->with('success',__('app.alert.success.user_deleted'));
$route = route('dash', []);
return redirect($route)
->with('success', __('app.alert.success.user_deleted'));
}
}
}
+4 -5
View File
@@ -31,26 +31,25 @@ class Kernel extends HttpKernel
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\ThrottleRequests::class.':60,1',
'bindings',
],
];
/**
* The application's route middleware.
* The application's middleware aliases.
*
* These middleware may be assigned to groups or used individually.
* Aliases may be used to conveniently assign middleware to routes and groups.
*
* @var array
*/
protected $routeMiddleware = [
protected $middlewareAliases = [
'allowed' => \App\Http\Middleware\CheckAllowed::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
+25 -16
View File
@@ -2,9 +2,12 @@
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
use App\User;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Session;
@@ -13,36 +16,42 @@ class CheckAllowed
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
* @throws AuthenticationException
*/
public function handle($request, Closure $next)
public function handle(Request $request, Closure $next): Response
{
$route = Route::currentRouteName();
$current_user = User::currentUser();
if(str_is('users*', $route)) {
if($current_user->id !== 1) {
// Non admin users can't access users management
if (str_is('users*', $route)) {
if ($current_user->getId() !== 1) {
return redirect()->route('dash');
}
}
if($route == 'dash') {
//print_r(User::all());
//die("here".var_dump($current_user->password));
if((bool)$current_user->public_front === true) return $next($request);
// Public access to frontpage
if ($route === 'dash' || $route === 'tags.show') {
if ((bool)$current_user->public_front === true) {
return $next($request);
}
}
if(empty($current_user->password)) return $next($request);
// Continue with passwordless user
if (empty($current_user->password)) {
return $next($request);
}
// Check if user is logged in as $current_user
if (Auth::check()) {
$loggedin_user = Auth::user();
if($loggedin_user->id === $current_user->id) return $next($request);
if ($loggedin_user->id === $current_user->getId()) {
return $next($request);
}
}
return Auth::authenticate();
// Redirect to login
Auth::authenticate();
return redirect()->route('user.select');
}
}
@@ -2,20 +2,17 @@
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Response;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
public function handle(Request $request, Closure $next, string $guard = null): Response
{
if (Auth::guard($guard)->check()) {
return redirect()->intended();
+2 -1
View File
@@ -9,9 +9,10 @@ class TrimStrings extends Middleware
/**
* The names of the attributes that should not be trimmed.
*
* @var array
* @var array<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
+3 -3
View File
@@ -2,8 +2,8 @@
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
@@ -12,12 +12,12 @@ class TrustProxies extends Middleware
*
* @var array
*/
protected $proxies;
protected $proxies = ['192.168.0.0/16', '172.16.0.0/12', '10.0.0.0/8', '127.0.0.1'];
/**
* The current proxy header mappings.
*
* @var array
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
class ValidateSignature extends Middleware
{
/**
* The names of the query string parameters that should be ignored.
*
* @var array<int, string>
*/
protected $except = [
// 'fbclid',
// 'utm_campaign',
// 'utm_content',
// 'utm_medium',
// 'utm_source',
// 'utm_term',
];
}
+267 -73
View File
@@ -2,131 +2,267 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\ClassLoader\ClassMapGenerator;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Database\Eloquent\Builder;
use App\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Casts\Attribute;
use stdClass;
use Symfony\Component\ClassLoader\ClassMapGenerator;
// @codingStandardsIgnoreStart
/**
* App\Item
*
* @property int $id
* @property string $title
* @property string|null $colour
* @property string|null $icon
* @property string $url
* @property string|null $description
* @property int $pinned
* @property int $order
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property int $type
* @property int $user_id
* @property string|null $class
* @property string|null $appid
* @property string|null $appdescription
* @property-read \Illuminate\Database\Eloquent\Collection|Item[] $children
* @property-read int|null $children_count
* @property-read string $droppable
* @property-read \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\UrlGenerator|mixed|string $link
* @property-read string $link_icon
* @property-read string $link_target
* @property-read string $link_type
* @property-read \Illuminate\Database\Eloquent\Collection|Item[] $parents
* @property-read int|null $parents_count
* @property-read \App\User|null $user
* @method static \Database\Factories\ItemFactory factory(...$parameters)
* @method static Builder|Item newModelQuery()
* @method static Builder|Item newQuery()
* @method static Builder|Item ofType($type)
* @method static \Illuminate\Database\Query\Builder|Item onlyTrashed()
* @method static Builder|Item pinned()
* @method static Builder|Item query()
* @method static Builder|Item whereAppdescription($value)
* @method static Builder|Item whereAppid($value)
* @method static Builder|Item whereClass($value)
* @method static Builder|Item whereColour($value)
* @method static Builder|Item whereCreatedAt($value)
* @method static Builder|Item whereDeletedAt($value)
* @method static Builder|Item whereDescription($value)
* @method static Builder|Item whereIcon($value)
* @method static Builder|Item whereId($value)
* @method static Builder|Item whereOrder($value)
* @method static Builder|Item wherePinned($value)
* @method static Builder|Item whereTitle($value)
* @method static Builder|Item whereType($value)
* @method static Builder|Item whereUpdatedAt($value)
* @method static Builder|Item whereUrl($value)
* @method static Builder|Item whereUserId($value)
* @method static \Illuminate\Database\Query\Builder|Item withTrashed()
* @method static \Illuminate\Database\Query\Builder|Item withoutTrashed()
* @mixin \Eloquent
*/
// @codingStandardsIgnoreEnd
class Item extends Model
{
use SoftDeletes;
protected static function boot()
use HasFactory;
protected static function boot(): void
{
parent::boot();
static::addGlobalScope('user_id', function (Builder $builder) {
$current_user = User::currentUser();
$builder->where('user_id', $current_user->id);
if ($current_user) {
$builder->where('user_id', $current_user->getId())->orWhere('user_id', 0);
} else {
$builder->where('user_id', 0);
}
});
}
//
protected $fillable = [
'title', 'url', 'colour', 'icon', 'description', 'pinned', 'order', 'type', 'class', 'user_id'
'title',
'url',
'colour',
'icon',
'appdescription',
'description',
'pinned',
'order',
'type',
'class',
'user_id',
'tag_id',
'appid',
];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
/**
* Scope a query to only include pinned items.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePinned($query)
public function scopePinned(Builder $query): Builder
{
return $query->where('pinned', 1);
}
public static function checkConfig($config)
{
if(empty($config)) {
// die(print_r($config));
if (empty($config)) {
$config = null;
} else {
$store = false;
//die(var_dump($config));
foreach($config as $key => $check) {
if($key == 'type') continue;
if($key == 'dataonly') continue;
if(!empty($check) && $check != '0') {
$store = true;
break;
}
}
//die(var_dump($store))
$config['enabled'] = ($store) ? true : false;
$config = json_encode($config);
}
return $config;
}
public function parents()
public function tags()
{
return $this->belongsToMany('App\Item', 'item_tag', 'item_id', 'tag_id');
}
public function children()
{
return $this->belongsToMany('App\Item', 'item_tag', 'tag_id', 'item_id');
$id = $this->id;
$tags = ItemTag::select('tag_id')->where('item_id', $id)->pluck('tag_id')->toArray();
$tagdetails = self::select('id', 'title', 'url', 'pinned')->whereIn('id', $tags)->get();
return $tagdetails;
}
protected function title(): Attribute
{
return Attribute::make(
get: fn (mixed $value) => ($value === 'app.dashboard' ? __('app.dashboard') : $value),
);
}
protected function tagUrl(): Attribute
{
return Attribute::make(
get: fn (mixed $value, array $attributes) => ($attributes['id'] === 0 ? '0-dash' : $attributes['url']),
);
}
public function getTagClass(): string
{
$tags = $this->tags();
$slugs = [];
foreach ($tags as $tag) {
if ($tag->id === 0) {
$tag->url = '0-dash';
}
if ($tag->url) {
$slugs[] = 'tag-'.$tag->url;
}
}
return implode(' ', $slugs);
}
public function getTagList(): string
{
$tags = $this->tags();
$titles = [];
// print_r($tags);
foreach ($tags as $tag) {
if ($tag->title) {
$titles[] = $tag->title;
}
}
return implode(', ', $titles);
}
public function parents(): BelongsToMany
{
return $this->belongsToMany(Item::class, 'item_tag', 'item_id', 'tag_id');
}
public function children(): BelongsToMany
{
return $this->belongsToMany(Item::class, 'item_tag', 'tag_id', 'item_id');
}
/**
* @return \Illuminate\Contracts\Foundation\Application|UrlGenerator|mixed|string
*/
public function getLinkAttribute()
{
if((int)$this->type === 1) {
return '/tag/'.$this->url;
if ((int) $this->type === 1) {
return url('tag/'.$this->url);
} else {
return $this->url;
}
}
public function getDroppableAttribute()
public function getDroppableAttribute(): string
{
if((int)$this->type === 1) {
if ((int) $this->type === 1) {
return ' droppable';
} else {
return '';
}
}
public function getLinkTargetAttribute()
public function getLinkTargetAttribute(): string
{
$target = Setting::fetch('window_target');
if((int)$this->type === 1 || $target === 'current') {
if ((int) $this->type === 1 || $target === 'current') {
return '';
} else {
return ' target="' . $target . '"';
return ' target="'.$target.'"';
}
}
public function getLinkIconAttribute()
public function getLinkIconAttribute(): string
{
if((int)$this->type === 1) {
if ((int) $this->type === 1) {
return 'fa-tag';
} else {
return 'fa-arrow-alt-to-right';
}
}
public function getLinkTypeAttribute()
public function getLinkTypeAttribute(): string
{
if((int)$this->type === 1) {
if ((int) $this->type === 1) {
return 'tags';
} else {
return 'items';
}
}
/**
* @param $class
* @return false|mixed|string
*/
public static function nameFromClass($class)
{
$explode = explode('\\', $class);
$name = end($explode);
return $name;
}
/**
* @param $query
* @param $type
* @return mixed
*/
public function scopeOfType($query, $type)
{
switch($type) {
switch ($type) {
case 'item':
$typeid = 0;
break;
@@ -138,63 +274,121 @@ class Item extends Model
return $query->where('type', $typeid);
}
public function enhanced()
public function enhanced(): bool
{
if(isset($this->class) && !empty($this->class)) {
/*if(isset($this->class) && !empty($this->class)) {
$app = new $this->class;
} else {
return false;
}
return (bool)($app instanceof \App\EnhancedApps);
return (bool)($app instanceof \App\EnhancedApps);*/
return $this->description !== null;
}
public function enabled()
/**
* @param $class
*/
public static function isEnhanced($class): bool
{
if($this->enhanced()) {
if (!class_exists($class, false) || $class === null || $class === 'null') {
return false;
}
$app = new $class;
return (bool) ($app instanceof EnhancedApps);
}
/**
* @param $class
* @return false|mixed
*/
public static function isSearchProvider($class)
{
if (!class_exists($class, false) || $class === null || $class === 'null') {
return false;
}
$app = new $class;
return ((bool) ($app instanceof SearchInterface)) ? $app : false;
}
public function enabled(): bool
{
if ($this->enhanced()) {
$config = $this->getconfig();
if($config) {
if ($config) {
return (bool) $config->enabled;
}
}
return false;
}
/**
* @return mixed|stdClass
*/
public function getconfig()
{
$explode = explode('\\', $this->class);
// $explode = explode('\\', $this->class);
if(!isset($this->description) || empty($this->description)) {
$config = new \stdClass;
$config->name = end($explode);
if (! isset($this->description) || empty($this->description)) {
$config = new stdClass;
// $config->name = end($explode);
$config->enabled = false;
$config->override_url = null;
$config->apikey = null;
return $config;
}
$config = json_decode($this->description);
$config->name = end($explode);
// $config->name = end($explode);
$config->url = $this->url;
if(isset($config->override_url) && !empty($config->override_url)) {
if (isset($config->override_url) && ! empty($config->override_url)) {
$config->url = $config->override_url;
} else {
$config->override_url = null;
}
return $config;
}
/**
* @param $class
*/
public static function applicationDetails($class): ?Application
{
if (! empty($class)) {
$name = self::nameFromClass($class);
$application = Application::where('name', $name)->first();
if ($application) {
return $application;
}
}
return null;
}
/**
* @param $class
*/
public static function getApplicationDescription($class): string
{
$details = self::applicationDetails($class);
if ($details !== null) {
return $details->description.' - '.$details->license;
}
return '';
}
/**
* Get the user that owns the item.
*/
public function user()
public function user(): BelongsTo
{
return $this->belongsTo('App\User');
}
return $this->belongsTo(User::class);
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\Pivot;
/**
* App\ItemTag
*
* @property int $item_id
* @property int $tag_id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag query()
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereItemId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereTagId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ItemTag whereUpdatedAt($value)
* @mixin \Eloquent
*/
class ItemTag extends Pivot
{
use HasFactory;
}
+29 -32
View File
@@ -2,15 +2,20 @@
namespace App\Jobs;
use App\Application;
use App\Item;
use App\SupportedApps;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Application;
use App\SupportedApps;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class ProcessApps implements ShouldQueue
class ProcessApps implements ShouldQueue, ShouldBeUnique
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
@@ -27,37 +32,29 @@ class ProcessApps implements ShouldQueue
/**
* Execute the job.
*
* @return void
* @throws GuzzleException
*/
public function handle()
public function handle(): void
{
$localapps = Application::all();
$list = json_decode(SupportedApps::getList()->getBody());
$validapps = [];
foreach($list->apps as $app) {
$validapps[] = $app->appid;
if(!file_exists(app_path('SupportedApps/'.className($app->name)))) {
SupportedApps::getFiles($app);
$application = new Application;
SupportedApps::saveApp($app, $application);
} else {
// check if there has been an update for this app
$localapp = $localapps->where('appid', $app->appid)->first();
if($localapp) {
if($localapp->sha !== $app->sha) {
SupportedApps::getFiles($app);
SupportedApps::saveApp($app, $localapp);
}
} else {
SupportedApps::getFiles($app);
$application = new Application;
SupportedApps::saveApp($app, $application);
Log::debug('Process Apps dispatched');
$localapps = Application::whereNull('class')->get();
$json = SupportedApps::getList()->getBody();
Storage::disk('local')->put('supportedapps.json', $json);
foreach ($localapps as $app) {
$app->class = $app->class();
$app->save();
}
$items = Item::whereNotNull('class')->get();
foreach ($items as $item) {
if (! file_exists(app_path('SupportedApps/'.Item::nameFromClass($item->class)))) {
$app = Application::where('class', $item->class)->first();
if ($app) {
Application::getApp($app->appid);
}
}
}
//$delete = Application::whereNotIn('appid', $validapps)->delete(); // delete any apps not in list
// removed the delete so local apps can be added
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Jobs;
use App\Application;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class UpdateApps implements ShouldQueue, ShouldBeUnique
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @throws GuzzleException
*/
public function handle(): void
{
Log::debug('Update of all apps triggered!');
$apps = Application::all('appid')->toArray();
// We onl update the apps that are actually in use by items
// 1 sec delay after each update to throttle the requests
foreach ($apps as $appKey => $app) {
Application::getApp($app['appid']);
sleep(1);
}
Log::debug('Update of all apps finished!');
Cache::lock('updateApps')->forceRelease();
}
public function failed($exception): void
{
Cache::lock('updateApps')->forceRelease();
}
}
+128 -74
View File
@@ -2,130 +2,184 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Artisan;
use Schema;
use App\Setting;
use App\User;
use App\Application;
use App\Jobs\ProcessApps;
use App\Jobs\UpdateApps;
use App\Setting;
use App\User;
use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
public function boot(): void
{
if(!is_file(base_path('.env'))) {
touch(base_path('.env'));
Artisan::call('key:generate');
}
if(!is_file(database_path('app.sqlite'))) {
// first time setup
touch(database_path('app.sqlite'));
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
//Cache
//Artisan::call('config:cache');
//Artisan::call('route:cache');
}
if(is_file(database_path('app.sqlite'))) {
if(Schema::hasTable('settings')) {
// check version to see if an upgrade is needed
$db_version = Setting::_fetch('version');
$app_version = config('app.version');
if(version_compare($app_version, $db_version) == 1) { // app is higher than db, so need to run migrations etc
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
}
} else {
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
}
}
$applications = Application::all();
if($applications->count() <= 0) {
if (class_exists('ZipArchive')) {
ProcessApps::dispatch();
} else {
die("You are missing php-zip");
}
if (! class_exists('ZipArchive')) {
die('You are missing php-zip');
}
if(!is_file(public_path('storage'))) {
$this->createEnvFile();
$this->setupDatabase();
if (! is_file(public_path('storage/.gitignore'))) {
Artisan::call('storage:link');
\Session::put('current_user', null);
}
// User specific settings need to go here as session isn't available at this point in the app
view()->composer('*', function ($view)
{
$applications = Application::all();
if(isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
if ($applications->count() <= 0) {
ProcessApps::dispatch();
}
$lang = Setting::fetch('language');
\App::setLocale($lang);
// User specific settings need to go here as session isn't available at this point in the app
view()->composer('*', function ($view) {
if (isset($_SERVER['HTTP_AUTHORIZATION']) && ! empty($_SERVER['HTTP_AUTHORIZATION'])) {
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
}
if(!\Auth::check()) {
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
if (! \Auth::check()) {
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])
&& ! empty($_SERVER['PHP_AUTH_USER']) && ! empty($_SERVER['PHP_AUTH_PW'])) {
$credentials = ['username' => $_SERVER['PHP_AUTH_USER'], 'password' => $_SERVER['PHP_AUTH_PW']];
if (\Auth::attempt($credentials)) {
if (\Auth::attempt($credentials, true)) {
// Authentication passed...
$user = \Auth::user();
//\Session::put('current_user', $user);
session(['current_user' => $user]);
session(['current_user' => $user]);
}
} elseif (isset($_SERVER['REMOTE_USER']) && ! empty($_SERVER['REMOTE_USER'])) {
$user = User::where('username', $_SERVER['REMOTE_USER'])->first();
if ($user) {
\Auth::login($user, true);
session(['current_user' => $user]);
}
}
}
$alt_bg = '';
if($bg_image = Setting::fetch('background_image')) {
$alt_bg = ' style="background-image: url(/storage/'.$bg_image.')"';
$trianglify = 'false';
$trianglify_seed = null;
if (Setting::fetch('trianglify')) {
$trianglify = 'true';
$trianglify_seed = Setting::fetch('trianglify_seed');
} elseif ($bg_image = Setting::fetch('background_image')) {
$alt_bg = ' style="background-image: url(storage/'.$bg_image.')"';
}
$lang = Setting::fetch('language');
\App::setLocale($lang);
$allusers = User::all();
$current_user = User::currentUser();
$view->with('alt_bg', $alt_bg );
$view->with('allusers', $allusers );
$view->with('current_user', $current_user );
});
$view->with('alt_bg', $alt_bg);
$view->with('trianglify', $trianglify);
$view->with('trianglify_seed', $trianglify_seed);
$view->with('allusers', $allusers);
$view->with('current_user', $current_user);
});
$this->app['view']->addNamespace('SupportedApps', app_path('SupportedApps'));
if (env('FORCE_HTTPS') === true) {
\URL::forceScheme('https');
}
if(env('APP_URL') != 'http://localhost') {
if (env('APP_URL') != 'http://localhost') {
\URL::forceRootUrl(env('APP_URL'));
}
}
/**
* Generate app key if missing and .env exists
*/
public function genKey(): void
{
if (is_file(base_path('.env'))) {
if (empty(env('APP_KEY'))) {
Artisan::call('key:generate', ['--force' => true, '--no-interaction' => true]);
}
}
}
/**
* Register any application services.
*
* @return void
*/
public function register()
public function register(): void
{
if ($this->app->isLocal()) {
$this->app->register(IdeHelperServiceProvider::class);
}
$this->app->singleton('settings', function () {
return new Setting();
});
}
/**
* Check if database needs an update or do first time database setup
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function setupDatabase(): void
{
$db_type = config()->get('database.default');
if ($db_type == 'sqlite') {
$db_file = database_path(env('DB_DATABASE', 'app.sqlite'));
if (! is_file($db_file)) {
touch($db_file);
}
}
if ($this->needsDBUpdate()) {
Artisan::call('migrate', ['--path' => 'database/migrations', '--force' => true, '--seed' => true]);
ProcessApps::dispatchSync();
$this->updateApps();
}
}
public function createEnvFile(): void
{
if (!is_file(base_path('.env'))) {
copy(base_path('.env.example'), base_path('.env'));
}
$this->genKey();
}
private function needsDBUpdate(): bool
{
if (!Schema::hasTable('settings')) {
return true;
}
$db_version = Setting::_fetch('version');
$app_version = config('app.version');
return version_compare($app_version, $db_version) === 1;
}
private function updateApps(): void
{
// This lock ensures that the job is not invoked multiple times.
// In 5 minutes all app updates should be finished.
$lock = Cache::lock('updateApps', 5*60);
if ($lock->get()) {
UpdateApps::dispatchAfterResponse();
}
}
}
+1 -6
View File
@@ -2,7 +2,6 @@
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
@@ -18,13 +17,9 @@ class AuthServiceProvider extends ServiceProvider
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->registerPolicies();
//
}
}
+2 -4
View File
@@ -2,17 +2,15 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
public function boot(): void
{
Broadcast::routes();
+9 -4
View File
@@ -2,7 +2,6 @@
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
@@ -20,13 +19,19 @@ class EventServiceProvider extends ServiceProvider
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
public function boot(): void
{
parent::boot();
//
}
/**
* Determine if events and listeners should be automatically discovered.
*/
public function shouldDiscoverEvents(): bool
{
return false;
}
}
+6 -17
View File
@@ -2,8 +2,8 @@
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
@@ -12,16 +12,13 @@ class RouteServiceProvider extends ServiceProvider
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
* REMOVED WITH LARAVEL 8 UPGRADE
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
public function boot(): void
{
//
@@ -30,10 +27,8 @@ class RouteServiceProvider extends ServiceProvider
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
public function map(): void
{
$this->mapApiRoutes();
@@ -46,13 +41,10 @@ class RouteServiceProvider extends ServiceProvider
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
protected function mapWebRoutes(): void
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
@@ -60,14 +52,11 @@ class RouteServiceProvider extends ServiceProvider
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
protected function mapApiRoutes(): void
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
+144
View File
@@ -0,0 +1,144 @@
<?php
namespace App;
use Cache;
use Form;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Request as Input;
use Yaml;
abstract class Search
{
/**
* List of all search providers
*
* @return Collection
*/
public static function providers(): Collection
{
$providers = self::standardProviders();
$providers = $providers + self::appProviders();
return collect($providers);
}
/**
* Gets details for a single provider
*
* @return false|object
*/
public static function providerDetails($provider)
{
$providers = self::providers();
if (! isset($providers[$provider])) {
return false;
}
return (object) $providers[$provider] ?? false;
}
/**
* Array of the standard providers
*
* @return array
*/
public static function standardProviders(): array
{
// $providers = json_decode(file_get_contents(storage_path('app/searchproviders.json')));
// print_r($providers);
$providers = Yaml::parseFile(storage_path('app/searchproviders.yaml'));
$all = [];
foreach ($providers as $key => $provider) {
$all[$key] = $provider;
$all[$key]['type'] = 'standard';
}
return $all;
}
/**
* Loops through users apps to see if app is a search provider, might be worth
* looking into caching this at some point
*
* @return array
*/
public static function appProviders(): array
{
$providers = [];
$userapps = Item::all();
foreach ($userapps as $app) {
if (empty($app->class)) {
continue;
}
if (($provider = Item::isSearchProvider($app->class)) !== false) {
$name = Item::nameFromClass($app->class);
$providers[$app->id] = [
'id' => $app->id,
'type' => $provider->type,
'class' => $app->class,
'url' => $app->url,
'name' => $app->title,
'colour' => $app->colour,
'icon' => $app->icon,
'description' => $app->description,
];
}
}
return $providers;
}
/**
* Outputs the search form
*
* @return string
*/
public static function form(): string
{
$output = '';
$homepage_search = Setting::fetch('homepage_search');
$search_provider = Setting::where('key', '=', 'search_provider')->first();
$user_search_provider = Setting::fetch('search_provider');
//die(print_r($search_provider));
//die(var_dump($user_search_provider));
// return early if search isn't applicable
if ((bool) $homepage_search !== true) {
return $output;
}
$user_search_provider = Input::get('p') ?? $user_search_provider ?? 'none';
if ((bool) $search_provider) {
if ((bool) $user_search_provider) {
$name = 'app.options.'.$user_search_provider;
$provider = self::providerDetails($user_search_provider);
$output .= '<div class="searchform">';
$output .= '<form action="'.url('search').'"'.getLinkTargetAttribute().' method="get">';
$output .= '<div id="search-container" class="input-container">';
$output .= '<select name="provider">';
foreach (self::providers() as $key => $searchprovider) {
$selected = ((string) $key === (string) $user_search_provider) ? ' selected="selected"' : '';
$output .= '<option value="'.$key.'"'.$selected.'>'.$searchprovider['name'].'</option>';
}
$output .= '</select>';
$output .= Form::text(
'q',
Input::get('q') ?? null,
[
'class' => 'homesearch',
'autofocus' => 'autofocus',
'placeholder' => __('app.settings.search').'...'
]
);
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
$output .= '</div>';
$output .= '</form>';
$output .= '</div>';
}
}
return $output;
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace App;
interface SearchInterface
{
public function getResults($query, $providerdetails);
}
+143 -142
View File
@@ -2,12 +2,47 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Input;
use Form;
use Illuminate\Support\Facades\Auth;
use App\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Http\Request;
use Illuminate\Session\SessionManager;
use Illuminate\Session\Store;
use Illuminate\Support\Facades\Input;
/**
* App\Setting
*
* @mixin Builder
* @property int $id
* @property int $group_id
* @property string $key
* @property string $type
* @property string|null $options
* @property string $label
* @property string|null $value
* @property string $order
* @property int $system
* @property-read mixed $edit_value
* @property-read mixed $list_value
* @property-read \App\SettingGroup|null $group
* @property-read \Illuminate\Database\Eloquent\Collection|\App\User[] $users
* @property-read int|null $users_count
* @method static Builder|Setting newModelQuery()
* @method static Builder|Setting newQuery()
* @method static Builder|Setting query()
* @method static Builder|Setting whereGroupId($value)
* @method static Builder|Setting whereId($value)
* @method static Builder|Setting whereKey($value)
* @method static Builder|Setting whereLabel($value)
* @method static Builder|Setting whereOptions($value)
* @method static Builder|Setting whereOrder($value)
* @method static Builder|Setting whereSystem($value)
* @method static Builder|Setting whereType($value)
* @method static Builder|Setting whereValue($value)
*/
class Setting extends Model
{
/**
@@ -18,7 +53,7 @@ class Setting extends Model
protected $table = 'settings';
protected $fillable = [
'id', 'group_id', 'key', 'type', 'options', 'label', 'value', 'order', 'system'
'id', 'group_id', 'key', 'type', 'options', 'label', 'value', 'order', 'system',
];
/**
@@ -35,47 +70,53 @@ class Setting extends Model
*/
protected static $cache = [];
/**
* @return array
*/
public static function getInput()
public static function getInput(Request $request): object
{
return (object) [
'value' => Input::get('value'),
'image' => Input::file('value'),
'value' => $request->input('value'),
'image' => $request->file('value'),
];
}
public function getListValueAttribute()
{
if((bool)$this->system === true) {
if ((bool) $this->system === true) {
$value = self::_fetch($this->key);
} else {
$value = self::fetch($this->key);
}
$this->value = $value;
switch($this->type) {
switch ($this->type) {
case 'image':
if(!empty($this->value)) {
$value = '<a href="'.asset('storage/'.$this->value).'" title="'.__('app.settings.view').'" target="_blank">'.__('app.settings.view').'</a>';
if (! empty($this->value)) {
$value = '<a href="'.asset('storage/'.$this->value).'" title="'.
__('app.settings.view').
'" target="_blank">'.
__('app.settings.view').
'</a>';
} else {
$value = __('app.options.none');
}
}
break;
case 'boolean':
if((bool)$this->value === true) {
if ((bool) $this->value === true) {
$value = __('app.options.yes');
} else {
$value = __('app.options.no');
}
}
break;
case 'select':
if(!empty($this->value) && $this->value !== 'none') {
$options = (array)json_decode($this->options);
$value = __($options[$this->value]);
if (! empty($this->value) && $this->value !== 'none') {
$options = (array) json_decode($this->options);
if ($this->key === 'search_provider') {
$options = Search::providers()->pluck('name', 'id')->toArray();
}
$value = (array_key_exists($this->value, $options))
? __($options[$this->value])
: __('app.options.none');
} else {
$value = __('app.options.none');
}
}
break;
default:
$value = __($this->value);
@@ -83,32 +124,46 @@ class Setting extends Model
}
return $value;
}
public function getEditValueAttribute()
{
if((bool)$this->system === true) {
if ((bool) $this->system === true) {
$value = self::_fetch($this->key);
} else {
$value = self::fetch($this->key);
}
$this->value = $value;
switch($this->type) {
switch ($this->type) {
case 'image':
$value = '';
if(isset($this->value) && !empty($this->value)) {
$value .= '<a class="setting-view-image" href="'.asset('storage/'.$this->value).'" title="'.__('app.settings.view').'" target="_blank"><img src="'.asset('storage/'.$this->value).'" /></a>';
if (isset($this->value) && ! empty($this->value)) {
$value .= '<a class="setting-view-image" href="'.
asset('storage/'.$this->value).
'" title="'.
__('app.settings.view').
'" target="_blank"><img src="'.
asset('storage/'.
$this->value).
'" /></a>';
}
$value .= Form::file('value', ['class' => 'form-control']);
if(isset($this->value) && !empty($this->value)) {
$value .= '<a class="settinglink" href="'.route('settings.clear', $this->id).'" title="'.__('app.settings.remove').'">'.__('app.settings.reset').'</a>';
if (isset($this->value) && ! empty($this->value)) {
$value .= '<a class="settinglink" href="'.
route('settings.clear', $this->id).
'" title="'.
__('app.settings.remove').
'">'.
__('app.settings.reset').
'</a>';
}
break;
case 'boolean':
$checked = false;
if(isset($this->value) && (bool)$this->value === true) $checked = true;
if (isset($this->value) && (bool) $this->value === true) {
$checked = true;
}
$set_checked = ($checked) ? ' checked="checked"' : '';
$value = '
<input type="hidden" name="value" value="0" />
@@ -120,168 +175,114 @@ class Setting extends Model
break;
case 'select':
$options = json_decode($this->options);
foreach($options as $key => $opt) {
if ($this->key === 'search_provider') {
$options = Search::providers()->pluck('name', 'id');
}
foreach ($options as $key => $opt) {
$options->$key = __($opt);
}
$value = Form::select('value', $options, null, ['class' => 'form-control']);
break;
case 'textarea':
$value = Form::textarea('value', null, ['class' => 'form-control', 'cols' => '44', 'rows' => '15']);
break;
default:
$value = Form::text('value', null, ['class' => 'form-control']);
break;
}
return $value;
}
public function group()
public function group(): BelongsTo
{
return $this->belongsTo('App\SettingGroup', 'group_id');
return $this->belongsTo(\App\SettingGroup::class, 'group_id');
}
/**
* @param string $key
*
* @return mixed
*/
public static function fetch($key)
public static function fetch(string $key)
{
$user = self::user();
return self::_fetch($key, $user);
}
// @codingStandardsIgnoreStart
/**
* @param string $key
*
* @return mixed
*/
public static function _fetch($key, $user=null)
public static function _fetch(string $key, $user = null)
{
#$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
#if (Setting::cached($cachekey)) {
# return Setting::$cache[$cachekey];
#} else {
$find = self::where('key', '=', $key)->first();
// @codingStandardsIgnoreEnd
//$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
//if (Setting::cached($cachekey)) {
// return Setting::$cache[$cachekey];
//} else {
$find = self::where('key', '=', $key)->first();
if (!is_null($find)) {
if((bool)$find->system === true) { // if system variable use global value
if (! is_null($find)) {
if ((bool) $find->system === true) { // if system variable use global value
$value = $find->value;
} else { // not system variable so use user specific value
// check if user specified value has been set
//print_r($user);
$usersetting = $user->settings()->where('id', $find->id)->first();
//print_r($user->settings);
//die(var_dump($usersetting));
//->pivot->value;
//echo "user: ".$user->id." --- ".$usersettings;
if (isset($usersetting) && ! empty($usersetting)) {
$value = $usersetting->pivot->uservalue;
} else { // if not get default from base setting
//$user->settings()->save($find, ['value' => $find->value]);
//$has_setting = $user->settings()->where('id', $find->id)->exists();
//if($has_setting) {
// $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
//} else {
// $user->settings()->save($find, ['uservalue' => (string)$find->value]);
//}
$value = $find->value;
} else { // not system variable so use user specific value
// check if user specified value has been set
//print_r($user);
$usersetting = $user->settings()->where('id', $find->id)->first();
//print_r($user->settings);
//die(var_dump($usersetting));
//->pivot->value;
//echo "user: ".$user->id." --- ".$usersettings;
if(isset($usersetting) && !empty($usersetting)) {
$value = $usersetting->pivot->uservalue;
} else { // if not get default from base setting
//$user->settings()->save($find, ['value' => $find->value]);
#$has_setting = $user->settings()->where('id', $find->id)->exists();
#if($has_setting) {
# $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
#} else {
# $user->settings()->save($find, ['uservalue' => (string)$find->value]);
#}
$value = $find->value;
}
}
#Setting::add($cachekey, $value);
return $value;
} else {
return false;
}
#}
//Setting::add($cachekey, $value);
return $value;
} else {
return false;
}
//}
}
/**
* @param string $key
* @param $value
*/
public static function add($key, $value)
public static function add(string $key, $value)
{
Setting::$cache[$key] = $value;
self::$cache[$key] = $value;
}
/**
* @param string $key
*
* @return bool
*/
public static function cached($key)
public static function cached(string $key): bool
{
return array_key_exists($key, Setting::$cache);
}
/**
* @return html
*/
public static function search()
{
$output = '';
$homepage_search = self::fetch('homepage_search');
$search_provider = self::where('key', '=', 'search_provider')->first();
$user_search_provider = self::fetch('search_provider');
//die(print_r($search_provider));
//die(var_dump($user_search_provider));
// return early if search isn't applicable
if((bool)$homepage_search !== true) return $output;
if($user_search_provider === 'none') return $output;
if(empty($user_search_provider)) return $output;
if(is_null($user_search_provider)) return $output;
if((bool)$homepage_search && (bool)$search_provider) {
$options = (array)json_decode($search_provider->options);
$name = $options[$user_search_provider];
if((bool)$user_search_provider) {
switch($user_search_provider) {
case 'google':
$url = 'https://www.google.com/search';
$var = 'q';
break;
case 'ddg':
$url = 'https://duckduckgo.com/';
$var = 'q';
break;
case 'bing':
$url = 'https://www.bing.com/search';
$var = 'q';
break;
case 'startpage':
$url = 'https://www.startpage.com/';
$var = 'q';
}
$output .= '<div class="searchform">';
$output .= Form::open(['url' => $url, 'method' => 'get']);
$output .= '<div class="input-container">';
$output .= Form::text($var, null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
$output .= '</div>';
$output .= Form::close();
$output .= '</div>';
}
}
return $output;
return array_key_exists($key, self::$cache);
}
/**
* The users that belong to the setting.
*/
public function users()
public function users(): BelongsToMany
{
return $this->belongsToMany('App\User')->using('App\SettingUser')->withPivot('uservalue');
return $this->belongsToMany(\App\User::class)->using(\App\SettingUser::class)->withPivot('uservalue');
}
/**
* @return \Illuminate\Contracts\Foundation\Application|SessionManager|Store|mixed
*/
public static function user()
{
return User::currentUser();
}
}
+19 -2
View File
@@ -3,7 +3,24 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* App\SettingGroup
*
* @property int $id
* @property string $title
* @property int $order
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Setting[] $settings
* @property-read int|null $settings_count
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup query()
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereOrder($value)
* @method static \Illuminate\Database\Eloquent\Builder|SettingGroup whereTitle($value)
* @mixin \Eloquent
*/
class SettingGroup extends Model
{
/**
@@ -20,8 +37,8 @@ class SettingGroup extends Model
*/
public $timestamps = false;
public function settings()
public function settings(): HasMany
{
return $this->hasMany('App\Setting', 'group_id');
return $this->hasMany(\App\Setting::class, 'group_id');
}
}
+14
View File
@@ -4,6 +4,20 @@ namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
/**
* App\SettingUser
*
* @property int $setting_id
* @property int $user_id
* @property string|null $uservalue
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser query()
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereSettingId($value)
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|SettingUser whereUservalue($value)
* @mixin \Eloquent
*/
class SettingUser extends Pivot
{
//
+125 -47
View File
@@ -1,27 +1,46 @@
<?php namespace App;
<?php
namespace App;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\ServerException;
use Illuminate\Support\Facades\Log;
use Psr\Http\Message\ResponseInterface;
abstract class SupportedApps
{
protected $jar = false;
protected $method = 'GET';
protected $error;
public function appTest($url, $attrs = [], $overridevars=false)
/**
* @param $url
* @param array $attrs
* @return object
* @throws GuzzleException
*/
public function appTest($url, array $attrs = []): object
{
if (empty($this->config->url)) {
return (object) [
'code' => 404,
'status' => 'No URL has been specified',
'response' => 'No URL has been specified',
];
}
$res = $this->execute($url, $attrs);
if($res == null) {
return (object)[
if ($res == null) {
return (object) [
'code' => null,
'status' => $this->error,
'response' => 'Connection failed',
];
}
switch($res->getStatusCode()) {
switch ($res->getStatusCode()) {
case 200:
$status = 'Successfully communicated with the API';
break;
@@ -35,83 +54,138 @@ abstract class SupportedApps
$status = 'Something went wrong... Code: '.$res->getStatusCode();
break;
}
return (object)[
return (object) [
'code' => $res->getStatusCode(),
'status' => $status,
'response' => $res->getBody(),
];
}
public function execute($url, $attrs = [], $overridevars=false, $overridemethod=false)
{
/**
* @param $url
* @param array $attrs
* @param array|bool|null $overridevars
* @param string|bool|null $overridemethod
* @return ResponseInterface|null
* @throws GuzzleException
*/
public function execute(
$url,
array $attrs = [],
$overridevars = null,
$overridemethod = null
): ?ResponseInterface {
$res = null;
$vars = ($overridevars !== false) ?
$overridevars : [
'http_errors' => false,
'timeout' => 15,
$vars = ($overridevars === null || $overridevars === false) ?
[
'http_errors' => false,
'timeout' => 15,
'connect_timeout' => 15,
];
] : $overridevars;
$client = new Client($vars);
$method = ($overridemethod !== false) ? $overridemethod : $this->method;
$method = ($overridemethod === null || $overridemethod === false) ? $this->method : $overridemethod;
try {
return $client->request($method, $url, $attrs);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
Log::error("Connection refused");
return $client->request($method, $url, $attrs);
} catch (ConnectException $e) {
Log::error('Connection refused');
Log::debug($e->getMessage());
$this->error = "Connection refused - ".(string) $e->getMessage();
} catch (\GuzzleHttp\Exception\ServerException $e) {
$this->error = 'Connection refused - '.(string) $e->getMessage();
} catch (ServerException $e) {
Log::debug($e->getMessage());
$this->error = (string) $e->getResponse()->getBody();
}
$this->error = 'General error connecting with API';
return $res;
}
/**
* @return void
*/
public function login()
{
}
public function normaliseurl($url, $addslash=true)
/**
* @param string $url
* @param bool $addslash
* @return string
*/
public function normaliseurl(string $url, bool $addslash = true): string
{
$url = rtrim($url, '/');
if($addslash) $url .= '/';
if ($addslash) {
$url .= '/';
}
return $url;
}
/**
* @param $status
* @param $data
* @return false|string
*/
public function getLiveStats($status, $data)
{
$className = get_class($this);
$className = $this::class;
$explode = explode('\\', $className);
$name = end($explode);
$html = view('SupportedApps::'.$name.'.livestats', $data)->with('data', $data)->render();
return json_encode(['status' => $status, 'html' => $html]);
//return
//return
}
public static function getList()
/**
* @return ResponseInterface
* @throws GuzzleException
*/
public static function getList(): ResponseInterface
{
$list_url = 'https://apps.heimdall.site/list';
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
// $list_url = 'https://apps.heimdall.site/list';
$list_url = config('app.appsource').'list.json';
$client = new Client(['http_errors' => false, 'verify' => false, 'timeout' => 15, 'connect_timeout' => 15]);
return $client->request('GET', $list_url);
}
public static function getFiles($app)
public static function configValue($item = null, $key = null)
{
$zipurl = $app->files;
$client = new Client(['http_errors' => false, 'timeout' => 60, 'connect_timeout' => 15]);
if (isset($item) && ! empty($item)) {
return $item->getconfig()->$key;
} else {
return null;
}
}
/**
* @param $app
* @return bool|false
* @throws GuzzleException
*/
public static function getFiles($app): bool
{
Log::debug("Download triggered for ".print_r($app, true));
$zipurl = config('app.appsource').'files/'.$app->sha.'.zip';
$client = new Client(['http_errors' => false, 'timeout' => 60, 'connect_timeout' => 15, 'verify' => false]);
$res = $client->request('GET', $zipurl);
if(!file_exists(app_path('SupportedApps'))) {
// Something went wrong?
if ($res->getStatusCode() !== 200) {
return false;
}
if (! file_exists(app_path('SupportedApps'))) {
mkdir(app_path('SupportedApps'), 0777, true);
}
@@ -124,31 +198,35 @@ abstract class SupportedApps
$zip->extractTo(app_path('SupportedApps')); // place in the directory with same name
$zip->close();
unlink($src); //Deleting the Zipped file
} else {
var_dump($x);
return false;
}
return true;
}
/**
* @param $details
* @param $app
* @return mixed
*/
public static function saveApp($details, $app)
{
$img_src = app_path('SupportedApps/'.className($details->name).'/'.$details->icon);
$img_dest = public_path('storage/supportedapps/'.$details->icon);
//die("i: ".$img_src);
copy($img_src, $img_dest);
$app->appid = $details->appid;
$app->name = $details->name;
$app->sha = $details->sha ?? null;
$app->icon = 'supportedapps/'.$details->icon;
$app->icon = 'icons/'.$details->icon;
$app->website = $details->website;
$app->license = $details->license;
$app->description = $details->description;
$appclass = $app->class();
$application = new $appclass;
$enhanced = (bool)($application instanceof \App\EnhancedApps);
$enhanced = (bool) ($application instanceof \App\EnhancedApps);
$app->class = $appclass;
$app->enhanced = $enhanced;
$app->tile_background = $details->tile_background;
$app->save();
}
}
return $app;
}
}
+58 -11
View File
@@ -2,13 +2,54 @@
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
// @codingStandardsIgnoreStart
/**
* App\User
*
* @property int $id
* @property string $username
* @property string $email
* @property string|null $avatar
* @property string|null $password
* @property string|null $autologin
* @property int $public_front
* @property string|null $remember_token
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Item[] $items
* @property-read int|null $items_count
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
* @property-read int|null $notifications_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Setting[] $settings
* @property-read int|null $settings_count
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|User query()
* @method static \Illuminate\Database\Eloquent\Builder|User whereAutologin($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereAvatar($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|User wherePublicFront($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereRememberToken($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUsername($value)
* @mixin \Eloquent
*/
// @codingStandardsIgnoreEnd
class User extends Authenticatable
{
use Notifiable;
use HasFactory;
/**
* The attributes that are mass assignable.
*
@@ -27,20 +68,28 @@ class User extends Authenticatable
'password', 'remember_token',
];
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* Get the items for the user.
*/
public function items()
public function items(): HasMany
{
return $this->hasMany('App\Item');
return $this->hasMany(Item::class);
}
/**
* The settings that belong to the user.
*/
public function settings()
public function settings(): BelongsToMany
{
return $this->belongsToMany('App\Setting')->withPivot('uservalue');
return $this->belongsToMany(Setting::class)->withPivot('uservalue');
}
public static function currentUser()
@@ -49,15 +98,13 @@ class User extends Authenticatable
if ($current_user) { // if logged in, set this user
return $current_user;
} else { // not logged in, get first user
$user = User::where('public_front',true)->first();
if(!$user) {
$user = User::first();
$user = self::where('public_front', true)->first();
if (! $user) {
$user = self::first();
}
session(['current_user' => $user]);
return $user;
}
}
}
+1 -1
View File
@@ -12,7 +12,7 @@
*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
/*
+44 -18
View File
@@ -1,36 +1,48 @@
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "^4.0",
"graham-campbell/github": "^7.5",
"guzzlehttp/guzzle": "^6.3",
"laravel/framework": "5.7.*",
"laravel/tinker": "~1.0",
"laravelcollective/html": "^5.5",
"php-http/guzzle6-adapter": "^1.1"
"php": "^8.1",
"graham-campbell/github": "^12.0",
"guzzlehttp/guzzle": "^7.4",
"laravel/framework": "^10.44",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"laravelcollective/html": "^6.4",
"nunomaduro/collision": "^6.3",
"symfony/yaml": "^6.2",
"ext-json": "*",
"ext-intl": "*",
"league/flysystem-aws-s3-v3": "^3.0",
"spatie/laravel-ignition": "^2.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~6.0",
"symfony/thanks": "^1.0"
"barryvdh/laravel-ide-helper": "^2.13",
"filp/whoops": "^2.8",
"mockery/mockery": "^1.4.4",
"phpunit/phpunit": "^9.5.10",
"squizlabs/php_codesniffer": "3.*",
"symfony/thanks": "^1.2",
"fakerphp/faker": "^1.9.1"
},
"autoload": {
"classmap": [
"database/seeds",
"database/seeders",
"database/factories"
],
"files": [
"app/Helper.php"
],
"psr-4": {
"App\\": "app/"
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
@@ -41,6 +53,7 @@
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-ide-helper"
]
}
},
@@ -54,11 +67,24 @@
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"@php artisan ide-helper:generate",
"@php artisan ide-helper:meta",
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
}
"optimize-autoloader": true,
"allow-plugins": {
"kylekatarnls/update-helper": true,
"symfony/thanks": true,
"php-http/discovery": true
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
Generated
+7347 -1931
View File
File diff suppressed because it is too large Load Diff
+40 -82
View File
@@ -1,5 +1,8 @@
<?php
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Facade;
return [
/*
@@ -13,8 +16,8 @@ return [
|
*/
'name' => env('APP_NAME', 'Heimdall'),
'version' => '2.1.0',
'name' => env('APP_NAME', 'Heimdall'),
'version' => '2.6.3',
/*
|--------------------------------------------------------------------------
@@ -40,7 +43,7 @@ return [
|
*/
'debug' => env('APP_DEBUG', false),
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
@@ -55,6 +58,9 @@ return [
'url' => env('APP_URL', 'http://localhost'),
'asset_url' => env('ASSET_URL', null),
'appsource' => env('APP_SOURCE', 'https://appslist.heimdall.site/'),
/*
|--------------------------------------------------------------------------
| Application Timezone
@@ -94,6 +100,19 @@ return [
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
@@ -111,20 +130,21 @@ return [
/*
|--------------------------------------------------------------------------
| Logging Configuration
| Maintenance Mode Driver
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
| These configuration options determine the driver used to determine and
| manage Laravel's "maintenance mode" status. The "cache" driver will
| allow maintenance mode to be controlled across multiple machines.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
| Supported drivers: "file", "cache"
|
*/
'log' => env('APP_LOG', 'single'),
'log_level' => env('APP_LOG_LEVEL', 'debug'),
'maintenance' => [
'driver' => 'file',
// 'store' => 'redis',
],
/*
|--------------------------------------------------------------------------
@@ -137,34 +157,7 @@ return [
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
'providers' => ServiceProvider::defaultProviders()->merge([
/*
* Package Service Providers...
*/
@@ -177,8 +170,7 @@ return [
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
])->toArray(),
/*
|--------------------------------------------------------------------------
@@ -191,47 +183,13 @@ return [
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Form' => Collective\Html\FormFacade::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Html' => Collective\Html\HtmlFacade::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'SupportedApps' => App\SupportedApps::class,
'aliases' => Facade::defaultAliases()->merge([
'EnhancedApps' => App\EnhancedApps::class,
],
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'SupportedApps' => App\SupportedApps::class,
'Yaml' => Symfony\Component\Yaml\Yaml::class,
])->toArray(),
];
+22 -3
View File
@@ -31,7 +31,7 @@ return [
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
| Supported: "session"
|
*/
@@ -44,6 +44,7 @@ return [
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
@@ -85,18 +86,36 @@ return [
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| The expiry time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
| The throttle setting is the number of seconds a user must wait before
| generating more password reset tokens. This prevents the user from
| quickly generating a very large amount of password reset tokens.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'table' => 'password_reset_tokens',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
+13 -1
View File
@@ -11,7 +11,7 @@ return [
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
| Supported: "pusher", "ably", "redis", "log", "null"
|
*/
@@ -37,8 +37,20 @@ return [
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
'ably' => [
'driver' => 'ably',
'key' => env('ABLY_KEY'),
],
'redis' => [
+27 -10
View File
@@ -1,5 +1,7 @@
<?php
use Illuminate\Support\Str;
return [
/*
@@ -11,8 +13,6 @@ return [
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
@@ -26,6 +26,9 @@ return [
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
| Supported drivers: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb", "octane", "null"
|
*/
'stores' => [
@@ -36,17 +39,20 @@ return [
'array' => [
'driver' => 'array',
'serialize' => false,
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
'lock_connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
'lock_path' => storage_path('framework/cache/data'),
],
'memcached' => [
@@ -57,7 +63,7 @@ return [
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
@@ -71,6 +77,20 @@ return [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'lock_connection' => 'default',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
'octane' => [
'driver' => 'octane',
],
],
@@ -80,15 +100,12 @@ return [
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
| When utilizing the APC, database, memcached, Redis, or DynamoDB cache
| stores there might be other applications using the same cache. For
| that reason, you may prefix every cache key to avoid collisions.
|
*/
'prefix' => env(
'CACHE_PREFIX',
str_slug(env('APP_NAME', 'laravel'), '_').'_cache'
),
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'),
];
+34
View File
@@ -0,0 +1,34 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
+39 -9
View File
@@ -1,5 +1,7 @@
<?php
use Illuminate\Support\Str;
return [
/*
@@ -13,7 +15,7 @@ return [
|
*/
'default' => env('DB_CONNECTION', 'sqlite'),
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
@@ -35,13 +37,15 @@ return [
'sqlite' => [
'driver' => 'sqlite',
//'database' => env('DB_DATABASE', database_path('database.sqlite')),
'database' => database_path(env('DB_DATABASE', 'app.sqlite')),
'url' => env('DATABASE_URL'),
'database' => database_path(env('DB_DATABASE', 'database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
@@ -51,12 +55,17 @@ return [
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
@@ -64,12 +73,14 @@ return [
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
@@ -77,6 +88,9 @@ return [
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
],
],
@@ -100,20 +114,36 @@ return [
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
+24 -14
View File
@@ -13,18 +13,7 @@ return [
|
*/
'default' => env('FILESYSTEM_DRIVER', 'public'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'default' => env('FILESYSTEM_DISK', 'local'),
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
@@ -35,9 +24,9 @@ return [
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
| been set up for each driver as an example of the required values.
|
| Supported Drivers: "local", "ftp", "s3", "rackspace"
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
*/
@@ -46,6 +35,7 @@ return [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'throw' => false,
],
'public' => [
@@ -53,6 +43,7 @@ return [
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'throw' => false,
],
's3' => [
@@ -61,8 +52,27 @@ return [
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
],
/*
|--------------------------------------------------------------------------
| Symbolic Links
|--------------------------------------------------------------------------
|
| Here you may configure the symbolic links that will be created when the
| `storage:link` Artisan command is executed. The array keys should be
| the locations of the links and the values should be their targets.
|
*/
'links' => [
public_path('storage') => storage_path('app/public'),
],
];
+54
View File
@@ -0,0 +1,54 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon", "argon2id"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 12),
'verify' => true,
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 65536,
'threads' => 1,
'time' => 4,
'verify' => true,
],
];
+131
View File
@@ -0,0 +1,131 @@
<?php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
use Monolog\Processor\PsrLogMessageProcessor;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Deprecations Log Channel
|--------------------------------------------------------------------------
|
| This option controls the log channel that should be used to log warnings
| regarding deprecated PHP and library features. This allows you to get
| your application ready for upcoming major versions of dependencies.
|
*/
'deprecations' => [
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
'trace' => false,
],
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'replace_placeholders' => true,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
'replace_placeholders' => true,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => env('LOG_LEVEL', 'critical'),
'replace_placeholders' => true,
],
'papertrail' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
],
'processors' => [PsrLogMessageProcessor::class],
],
'stderr' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
'processors' => [PsrLogMessageProcessor::class],
],
'syslog' => [
'driver' => 'syslog',
'level' => env('LOG_LEVEL', 'debug'),
'facility' => LOG_USER,
'replace_placeholders' => true,
],
'errorlog' => [
'driver' => 'errorlog',
'level' => env('LOG_LEVEL', 'debug'),
'replace_placeholders' => true,
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
'emergency' => [
'path' => storage_path('logs/laravel.log'),
],
],
];
+76 -65
View File
@@ -4,45 +4,97 @@ return [
/*
|--------------------------------------------------------------------------
| Mail Driver
| Default Mailer
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
| This option controls the default mailer that is used to send any email
| messages sent by your application. Alternative mailers may be setup
| and used as needed; however, this mailer will be used by default.
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'),
'default' => env('MAIL_MAILER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
| Mailer Configurations
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
| Here you may configure all of the mailers used by your application plus
| their respective settings. Several examples have been configured for
| you and you are free to add your own as your application requires.
|
| Laravel supports a variety of mail "transport" drivers to be used while
| sending an e-mail. You will specify which one you are using for your
| mailers below. You are free to add additional mailers as required.
|
| Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2",
| "postmark", "log", "array", "failover", "roundrobin"
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'url' => env('MAIL_URL'),
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'local_domain' => env('MAIL_EHLO_DOMAIN'),
],
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'ses' => [
'transport' => 'ses',
],
'port' => env('MAIL_PORT', 587),
'postmark' => [
'transport' => 'postmark',
// 'message_stream_id' => null,
// 'client' => [
// 'timeout' => 5,
// ],
],
'mailgun' => [
'transport' => 'mailgun',
// 'client' => [
// 'timeout' => 5,
// ],
],
'sendmail' => [
'transport' => 'sendmail',
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
],
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
],
'array' => [
'transport' => 'array',
],
'failover' => [
'transport' => 'failover',
'mailers' => [
'smtp',
'log',
],
],
'roundrobin' => [
'transport' => 'roundrobin',
'mailers' => [
'ses',
'postmark',
],
],
],
/*
|--------------------------------------------------------------------------
@@ -60,47 +112,6 @@ return [
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
+18 -10
View File
@@ -4,18 +4,16 @@ return [
/*
|--------------------------------------------------------------------------
| Default Queue Driver
| Default Queue Connection Name
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null"
| syntax for every one. Here you may define a default connection.
|
*/
'default' => env('QUEUE_DRIVER', 'sync'),
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
@@ -26,6 +24,8 @@ return [
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
@@ -39,6 +39,7 @@ return [
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
'beanstalkd' => [
@@ -46,22 +47,28 @@ return [
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
'after_commit' => false,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('SQS_KEY', 'your-public-key'),
'secret' => env('SQS_SECRET', 'your-secret-key'),
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('SQS_REGION', 'us-east-1'),
'queue' => env('SQS_QUEUE', 'default'),
'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'after_commit' => false,
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],
],
@@ -78,6 +85,7 @@ return [
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
+12 -16
View File
@@ -8,31 +8,27 @@ return [
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
'scheme' => 'https',
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
];
+29 -12
View File
@@ -1,5 +1,7 @@
<?php
use Illuminate\Support\Str;
return [
/*
@@ -12,7 +14,7 @@ return [
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "array"
| "memcached", "redis", "dynamodb", "array"
|
*/
@@ -70,7 +72,7 @@ return [
|
*/
'connection' => null,
'connection' => env('SESSION_CONNECTION'),
/*
|--------------------------------------------------------------------------
@@ -90,13 +92,15 @@ return [
| Session Cache Store
|--------------------------------------------------------------------------
|
| When using the "apc" or "memcached" session drivers, you may specify a
| cache store that should be used for these sessions. This value must
| correspond with one of the application's configured cache stores.
| While using one of the framework's cache driven session backends you may
| list a cache store that should be used for these sessions. This value
| must match with one of the application's configured cache "stores".
|
| Affects: "apc", "dynamodb", "memcached", "redis"
|
*/
'store' => null,
'store' => env('SESSION_STORE'),
/*
|--------------------------------------------------------------------------
@@ -124,7 +128,7 @@ return [
'cookie' => env(
'SESSION_COOKIE',
str_slug(env('APP_NAME', 'laravel'), '_').'_session'
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*
@@ -151,7 +155,7 @@ return [
|
*/
'domain' => env('SESSION_DOMAIN', null),
'domain' => env('SESSION_DOMAIN'),
/*
|--------------------------------------------------------------------------
@@ -160,11 +164,11 @@ return [
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
| the cookie from being sent to you when it can't be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', false),
'secure' => env('SESSION_SECURE_COOKIE'),
/*
|--------------------------------------------------------------------------
@@ -186,12 +190,25 @@ return [
|
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| do not enable this as other CSRF protection services are in place.
| will set this value to "lax" since this is a secure default value.
|
| Supported: "lax", "strict"
| Supported: "lax", "strict", "none", null
|
*/
'same_site' => null,
/*
|--------------------------------------------------------------------------
| Partitioned Cookies
|--------------------------------------------------------------------------
|
| Setting this value to true will tie the cookie to the top-level site for
| a cross-site context. Partitioned cookies are accepted by the browser
| when flagged "secure" and the Same-Site attribute is set to "none".
|
*/
'partitioned' => false,
];
+4 -1
View File
@@ -28,6 +28,9 @@ return [
|
*/
'compiled' => realpath(storage_path('framework/views')),
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Item;
use Illuminate\Database\Eloquent\Factories\Factory;
class ItemFactory extends Factory
{
/**
* Define the model's default state.
*/
public function definition(): array
{
return [
'title' => $this->faker->unique()->text(),
'url' => $this->faker->unique()->url(),
];
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Database\Factories;
use App\Item;
use App\ItemTag;
use Illuminate\Database\Eloquent\Factories\Factory;
class ItemTagFactory extends Factory
{
/**
* Define the model's default state.
*/
public function definition(): array
{
return [];
}
}
+37 -19
View File
@@ -1,23 +1,41 @@
<?php
use Faker\Generator as Faker;
namespace Database\Factories;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
use Illuminate\Support\Facades\Hash;
use App\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
protected static ?string $password;
public function definition(): array
{
return [
'username' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'password' => static::$password ??= Hash::make('password'),
'public_front' => 1,
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): Factory
{
return $this->state(function (array $attributes) {
return [
'email_verified_at' => null,
];
});
}
}
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateItemsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('items', function (Blueprint $table) {
$table->increments('id');
@@ -29,11 +27,9 @@ class CreateItemsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('items');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSettingsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
@@ -28,11 +26,9 @@ class CreateSettingsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('settings');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSettingGroupsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('setting_groups', function (Blueprint $table) {
$table->increments('id');
@@ -22,11 +20,9 @@ class CreateSettingGroupsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('setting_groups');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddColumnsToItemsForGroups extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->integer('type')->default(0)->index(); // 0 = item, 1 = category
@@ -20,13 +18,11 @@ class AddColumnsToItemsForGroups extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
$table->dropColumn(['type']);
});
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ItemTag extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('item_tag', function (Blueprint $table) {
$table->integer('item_id')->unsigned()->index();
@@ -25,11 +23,9 @@ class ItemTag extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('item_tag');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
@@ -28,11 +26,9 @@ class CreateUsersTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('users');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePasswordResetsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
@@ -22,11 +20,9 @@ class CreatePasswordResetsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('password_resets');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserIdToItemsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->integer('user_id')->default(1)->index(); // 0 = item, 1 = category
@@ -20,13 +18,11 @@ class AddUserIdToItemsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
$table->dropColumn(['user_id']);
});
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSettingUserPivotTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('setting_user', function (Blueprint $table) {
$table->integer('setting_id')->unsigned()->index();
@@ -25,11 +23,9 @@ class CreateSettingUserPivotTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('setting_user');
}
}
};
@@ -1,20 +1,17 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateApplicationsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('applications', function (Blueprint $table) {
$table->string('appid')->unique();
$table->string('name')->unique();
$table->string('sha')->unique()->nullable();
@@ -31,11 +28,9 @@ class CreateApplicationsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('applications');
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddClassToItemsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->string('class')->nullable();
@@ -20,13 +18,11 @@ class AddClassToItemsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
$table->dropColumn(['class']);
});
}
}
};
@@ -1,17 +1,15 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateJobsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
@@ -26,11 +24,9 @@ class CreateJobsTable extends Migration
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('jobs');
}
}
};
@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('failed_jobs');
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->string('appid')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
$table->dropColumn(['appid']);
});
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->string('class')->nullable()->index();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('applications', function (Blueprint $table) {
$table->dropColumn(['class']);
});
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('items', function (Blueprint $table) {
$table->text('appdescription')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('items', function (Blueprint $table) {
//
});
}
};
@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::rename('password_resets', 'password_reset_tokens');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::rename('password_reset_tokens', 'password_resets');
}
};
@@ -1,15 +1,15 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
public function run(): void
{
$this->call(SettingsSeeder::class);
$this->call(UsersSeeder::class);
+354
View File
@@ -0,0 +1,354 @@
<?php
namespace Database\Seeders;
use App\Setting;
use App\SettingGroup;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Locale;
class SettingsSeeder extends Seeder
{
/**
* @return false|string
*/
public static function getSupportedLanguageMap()
{
if (! class_exists('Locale')) {
Log::info('PHP Extension Intl not found. Falling back to English language support only.');
return json_encode(['en' => 'English']);
}
$languageDirectories = array_filter(glob(lang_path().'/*'), 'is_dir');
$result = [];
foreach ($languageDirectories as $languageDirectory) {
$language = self::getLanguageFromDirectory($languageDirectory);
$resultNative = mb_convert_case(
Locale::getDisplayLanguage($language.'-', $language),
MB_CASE_TITLE,
'UTF-8'
);
$resultEn = ucfirst(Locale::getDisplayLanguage($language, 'en'));
$result[$language] = "$resultNative ($resultEn)";
}
return json_encode($result);
}
/**
* @param $languageDirectory
* @return false|string[]
*/
public static function getLanguageFromDirectory($languageDirectory)
{
$directories = explode('/', $languageDirectory);
return $directories[array_key_last($directories)];
}
/**
* Run the database seeds.
*/
public function run(): void
{
// Groups
if (! $setting_group = SettingGroup::find(1)) {
$setting_group = new SettingGroup;
$setting_group->id = 1;
$setting_group->title = 'app.settings.system';
$setting_group->order = 0;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.system';
$setting_group->save();
}
if (! $setting_group = SettingGroup::find(2)) {
$setting_group = new SettingGroup;
$setting_group->id = 2;
$setting_group->title = 'app.settings.appearance';
$setting_group->order = 1;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.appearance';
$setting_group->save();
}
if (! $setting_group = SettingGroup::find(3)) {
$setting_group = new SettingGroup;
$setting_group->id = 3;
$setting_group->title = 'app.settings.miscellaneous';
$setting_group->order = 2;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.miscellaneous';
$setting_group->save();
}
if (! $setting_group = SettingGroup::find(4)) {
$setting_group = new SettingGroup;
$setting_group->id = 4;
$setting_group->title = 'app.settings.advanced';
$setting_group->order = 3;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.advanced';
$setting_group->save();
}
if ($version = Setting::find(1)) {
$version->label = 'app.settings.version';
$version->value = config('app.version');
$version->save();
} else {
$setting = new Setting;
$setting->id = 1;
$setting->group_id = 1;
$setting->key = 'version';
$setting->type = 'text';
$setting->label = 'app.settings.version';
$setting->value = config('app.version');
$setting->system = true;
$setting->save();
}
if (! $setting = Setting::find(2)) {
$setting = new Setting;
$setting->id = 2;
$setting->group_id = 2;
$setting->key = 'background_image';
$setting->type = 'image';
$setting->label = 'app.settings.background_image';
$setting->save();
} else {
$setting->label = 'app.settings.background_image';
$setting->save();
}
if (! $setting = Setting::find(3)) {
$setting = new Setting;
$setting->id = 3;
$setting->group_id = 3;
$setting->key = 'homepage_search';
$setting->type = 'boolean';
$setting->label = 'app.settings.homepage_search';
$setting->save();
} else {
$setting->label = 'app.settings.homepage_search';
$setting->save();
}
$options = json_encode([
'none' => 'app.options.none',
'google' => 'app.options.google',
'ddg' => 'app.options.ddg',
'qwant' => 'app.options.qwant',
'bing' => 'app.options.bing',
'startpage' => 'app.options.startpage',
]);
if (! $setting = Setting::find(4)) {
$setting = new Setting;
$setting->id = 4;
$setting->group_id = 3;
$setting->key = 'search_provider';
$setting->type = 'select';
$setting->options = $options;
$setting->label = 'app.settings.search_provider';
$setting->save();
} else {
$setting->options = $options;
$setting->label = 'app.settings.search_provider';
$setting->save();
}
$language_options = SettingsSeeder::getSupportedLanguageMap();
if ($languages = Setting::find(5)) {
$languages->options = $language_options;
$languages->save();
} else {
$setting = new Setting;
$setting->id = 5;
$setting->group_id = 1;
$setting->key = 'language';
$setting->type = 'select';
$setting->label = 'app.settings.language';
$setting->options = $language_options;
$setting->value = 'en';
$setting->save();
}
if (! $setting = Setting::find(12)) {
$setting = new Setting;
$setting->id = 12;
$setting->group_id = 2;
$setting->key = 'trianglify';
$setting->type = 'boolean';
$setting->label = 'app.settings.trianglify';
$setting->save();
} else {
$setting->label = 'app.settings.trianglify';
$setting->save();
}
if (! $setting = Setting::find(13)) {
$setting = new Setting;
$setting->id = 13;
$setting->group_id = 2;
$setting->key = 'trianglify_seed';
$setting->type = 'text';
$setting->value = 'heimdall';
$setting->label = 'app.settings.trianglify_seed';
$setting->save();
} else {
$setting->label = 'app.settings.trianglify_seed';
$setting->save();
}
$window_target_options = json_encode([
'current' => 'app.settings.window_target.current',
'heimdall' => 'app.settings.window_target.one',
'_blank' => 'app.settings.window_target.new',
]);
if (! $setting = Setting::find(7)) {
$setting = new Setting;
$setting->id = 7;
$setting->group_id = 3;
$setting->key = 'window_target';
$setting->type = 'select';
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->value = 'heimdall';
$setting->save();
} else {
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->save();
}
if ($support = Setting::find(8)) {
$support->label = 'app.settings.support';
$support->value =
'<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a>'.
' | '.
'<a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a>'.
' | '.
'<a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$support->save();
} else {
$setting = new Setting;
$setting->id = 8;
$setting->group_id = 1;
$setting->key = 'support';
$setting->type = 'text';
$setting->label = 'app.settings.support';
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a>'.
' | '.
'<a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a>'.
' | '.
'<a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$setting->system = true;
$setting->save();
}
if ($donate = Setting::find(9)) {
$donate->label = 'app.settings.donate';
$donate->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$donate->save();
} else {
$setting = new Setting;
$setting->id = 9;
$setting->group_id = 1;
$setting->key = 'donate';
$setting->type = 'text';
$setting->label = 'app.settings.donate';
$setting->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$setting->system = true;
$setting->save();
}
if (! $setting = Setting::find(10)) {
$setting = new Setting;
$setting->id = 10;
$setting->group_id = 4;
$setting->key = 'custom_css';
$setting->type = 'textarea';
$setting->label = 'app.settings.custom_css';
$setting->value = '';
$setting->save();
} else {
$setting->type = 'textarea';
$setting->group_id = 4;
$setting->label = 'app.settings.custom_css';
$setting->save();
}
if (! $setting = Setting::find(11)) {
$setting = new Setting;
$setting->id = 11;
$setting->group_id = 4;
$setting->key = 'custom_js';
$setting->type = 'textarea';
$setting->label = 'app.settings.custom_js';
$setting->value = '';
$setting->save();
} else {
$setting->type = 'textarea';
$setting->group_id = 4;
$setting->label = 'app.settings.custom_js';
$setting->save();
}
if (! $home_tag = \App\Item::find(0)) {
$home_tag = new \App\Item;
$home_tag->id = 0;
$home_tag->title = 'app.dashboard';
$home_tag->pinned = 0;
$home_tag->url = '';
$home_tag->type = 1;
$home_tag->user_id = 0;
$home_tag->save();
$home_tag_id = $home_tag->id;
if ($home_tag_id != 0) {
Log::info("Home Tag returned with id $home_tag_id from db! Changing to 0.");
DB::update('update items set id = 0 where id = ?', [$home_tag_id]);
}
$homeapps = \App\Item::withoutGlobalScope('user_id')->doesntHave('parents')->get();
foreach ($homeapps as $app) {
if ($app->id === 0) {
continue;
}
$app->parents()->attach(0);
}
}
$tag_options = json_encode([
'folders' => 'app.settings.folders',
'tags' => 'app.settings.tags',
'categories' => 'app.settings.categories',
]);
if (! $setting = Setting::find(14)) {
$setting = new Setting;
$setting->id = 14;
$setting->group_id = 2;
$setting->key = 'treat_tags_as';
$setting->type = 'select';
$setting->options = $tag_options;
$setting->value = 'folders';
$setting->label = 'app.settings.treat_tags_as';
$setting->save();
} else {
$setting->options = $tag_options;
$setting->label = 'app.settings.treat_tags_as';
$setting->save();
}
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace Database\Seeders;
use App\User;
use Illuminate\Database\Seeder;
class UsersSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Groups
if (!User::find(1)) {
$user = new User;
$user->username = 'admin';
$user->email = 'admin@test.com';
$user->password = null;
$user->save();
$user_id = $user->id;
if ($user_id != 1) {
Log::info("First User returned with id $user_id from db! Changing to 1.");
DB::update('update users set id = 1 where id = ?', [$user_id]);
}
}
}
}
-197
View File
@@ -1,197 +0,0 @@
<?php
use Illuminate\Database\Seeder;
use App\Setting;
use App\SettingGroup;
class SettingsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// Groups
if(!$setting_group = SettingGroup::find(1)) {
$setting_group = new SettingGroup;
$setting_group->id = 1;
$setting_group->title = 'app.settings.system';
$setting_group->order = 0;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.system';
$setting_group->save();
}
if(!$setting_group = SettingGroup::find(2)) {
$setting_group = new SettingGroup;
$setting_group->id = 2;
$setting_group->title = 'app.settings.appearance';
$setting_group->order = 1;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.appearance';
$setting_group->save();
}
if(!$setting_group = SettingGroup::find(3)) {
$setting_group = new SettingGroup;
$setting_group->id = 3;
$setting_group->title = 'app.settings.miscellaneous';
$setting_group->order = 2;
$setting_group->save();
} else {
$setting_group->title = 'app.settings.miscellaneous';
$setting_group->save();
}
if($version = Setting::find(1)) {
$version->label = 'app.settings.version';
$version->value = config('app.version');
$version->save();
} else {
$setting = new Setting;
$setting->id = 1;
$setting->group_id = 1;
$setting->key = 'version';
$setting->type = 'text';
$setting->label = 'app.settings.version';
$setting->value = config('app.version');
$setting->system = true;
$setting->save();
}
if(!$setting = Setting::find(2)) {
$setting = new Setting;
$setting->id = 2;
$setting->group_id = 2;
$setting->key = 'background_image';
$setting->type = 'image';
$setting->label = 'app.settings.background_image';
$setting->save();
} else {
$setting->label = 'app.settings.background_image';
$setting->save();
}
if(!$setting = Setting::find(3)) {
$setting = new Setting;
$setting->id = 3;
$setting->group_id = 3;
$setting->key = 'homepage_search';
$setting->type = 'boolean';
$setting->label = 'app.settings.homepage_search';
$setting->save();
} else {
$setting->label = 'app.settings.homepage_search';
$setting->save();
}
$options = json_encode([
'none' => 'app.options.none',
'google' => 'app.options.google',
'ddg' => 'app.options.ddg',
'bing' => 'app.options.bing',
'startpage' => 'app.options.startpage',
]);
if(!$setting = Setting::find(4)) {
$setting = new Setting;
$setting->id = 4;
$setting->group_id = 3;
$setting->key = 'search_provider';
$setting->type = 'select';
$setting->options = $options;
$setting->label = 'app.settings.search_provider';
$setting->save();
} else {
$setting->options = $options;
$setting->label = 'app.settings.search_provider';
$setting->save();
}
$language_options = json_encode([
'de' => 'Deutsch (German)',
'en' => 'English',
'fi' => 'Suomi (Finnish)',
'fr' => 'Français (French)',
'it' => 'Italiano (Italian)',
'no' => 'Norsk (Norwegian)',
'pl' => 'Polski (Polish)',
'sv' => 'Svenska (Swedish)',
'es' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
]);
if($languages = Setting::find(5)) {
$languages->options = $language_options;
$languages->save();
} else {
$setting = new Setting;
$setting->id = 5;
$setting->group_id = 1;
$setting->key = 'language';
$setting->type = 'select';
$setting->label = 'app.settings.language';
$setting->options = $language_options;
$setting->value = 'en';
$setting->save();
}
$window_target_options = json_encode([
'current' => 'app.settings.window_target.current',
'heimdall' => 'app.settings.window_target.one',
'_blank' => 'app.settings.window_target.new',
]);
if(!$setting = Setting::find(7)) {
$setting = new Setting;
$setting->id = 7;
$setting->group_id = 3;
$setting->key = 'window_target';
$setting->type = 'select';
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->value = 'heimdall';
$setting->save();
} else {
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->save();
}
if($support = Setting::find(8)) {
$support->label = 'app.settings.support';
$support->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$support->save();
} else {
$setting = new Setting;
$setting->id = 8;
$setting->group_id = 1;
$setting->key = 'support';
$setting->type = 'text';
$setting->label = 'app.settings.support';
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$setting->system = true;
$setting->save();
}
if($donate = Setting::find(9)) {
$donate->label = 'app.settings.donate';
$donate->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$donate->save();
} else {
$setting = new Setting;
$setting->id = 9;
$setting->group_id = 1;
$setting->key = 'donate';
$setting->type = 'text';
$setting->label = 'app.settings.donate';
$setting->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$setting->system = true;
$setting->save();
}
}
}
-27
View File
@@ -1,27 +0,0 @@
<?php
use Illuminate\Database\Seeder;
use App\User;
class UsersSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// Groups
if(!$user = User::find(1)) {
$user = new User;
$user->id = 1;
$user->username = 'admin';
$user->email = 'admin@test.com';
$user->password = null;
$user->save();
} else {
//$user->save();
}
}
}
+133
View File
@@ -0,0 +1,133 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| App Language Lines
|--------------------------------------------------------------------------
|
*/
'settings.system' => 'Sistema',
'settings.appearance' => 'Aparência',
'settings.miscellaneous' => 'Diversos',
'settings.support' => 'Ajuda',
'settings.donate' => 'Doar',
'settings.version' => 'Versão',
'settings.background_image' => 'Imagem de fundo',
'settings.trianglify' => 'Trianglify',
'settings.trianglify_seed' => 'Trianglify Random Seed',
'settings.window_target' => 'Link é aberto em',
'settings.window_target.current' => 'Abra nesta aba',
'settings.window_target.one' => 'Abra na mesma aba',
'settings.window_target.new' => 'Abra em uma nova aba',
'settings.homepage_search' => 'Pesquisa na página inicial',
'settings.search_provider' => 'Provedor de pesquisa',
'settings.language' => 'Idioma',
'settings.reset' => 'Redefinir de volta ao padrão',
'settings.remove' => 'Remover',
'settings.search' => 'busca',
'settings.no_items' => 'Nenhum item encontrado',
'settings.advanced' => 'Avançado',
'settings.custom_css' => 'CSS Customizado',
'settings.custom_js' => 'JavaScript Customizado',
'settings.label' => 'Rótulo',
'settings.value' => 'Valor',
'settings.edit' => 'Editar',
'settings.view' => 'Ver',
'options.none' => '- não configurado -',
'options.google' => 'Google',
'options.ddg' => 'DuckDuckGo',
'options.bing' => 'Bing',
'options.qwant' => 'Qwant',
'options.startpage' => 'Página inicial',
'options.yes' => 'Sim',
'options.no' => 'Não',
'options.nzbhydra' => 'NZBHydra',
'options.jackett' => 'Jackett',
'buttons.save' => 'Salvar',
'buttons.cancel' => 'Cancelar',
'buttons.add' => 'Adicionar',
'buttons.upload' => 'Carregar um arquivo',
'buttons.downloadapps' => 'Atualizar lista de Apps',
'dashboard' => 'Página Inicial do dashboard',
'dashboard.reorder' => 'Reordenar e fixar itens',
'dashboard.settings' => 'Configurações',
'dash.pin_item' => 'Fixar o item na dashboard',
'dash.no_apps' => 'Atualmente não há aplicativos fixados, :link1 ou :link2',
'dash.link1' => 'Adicionar um aplivativo aqui',
'dash.link2' => 'Fixar um item na dashboard',
'dash.pinned_items' => 'Itens fixados',
'apps.app_list' => 'Lista de aplicativos',
'apps.view_trash' => 'Ver lixo',
'apps.add_application' => 'Adicionar aplicativo',
'apps.application_name' => 'Nome do aplicativo',
'apps.colour' => 'Cor',
'apps.icon' => 'Ícone',
'app.import' => 'Importar',
'apps.pinned' => 'Fixado',
'apps.title' => 'Título',
'apps.hex' => 'Cor hexadecimal',
'apps.username' => 'Nome de usuário',
'apps.password' => 'Senha',
'apps.config' => 'Configuração',
'apps.apikey' => 'API Key',
'apps.enable' => 'Habilitar',
'apps.tag_list' => 'Lista de tags',
'apps.add_tag' => 'Adicionar tag',
'apps.tag_name' => 'Nome da tag',
'apps.tags' => 'Tags',
'apps.override' => 'Se diferente do URL principal',
'apps.preview' => 'Vizualizar',
'apps.apptype' => 'Tipo de Aplicativo',
'apps.website' => 'Website',
'apps.description' => 'Descrição',
'apps.only_admin_account' => 'Somente se tiver conta admin!',
'apps.autologin_url' => 'URL de login automático',
'apps.show_deleted' => 'Mostrando Aplicativos Apagados',
'user.user_list' => 'Comercial',
'user.add_user' => 'Adicionar usuários',
'user.username' => 'Nome de usuário',
'user.avatar' => 'Avatar',
'user.email' => 'O email',
'user.password_confirm' => 'Confirme a Senha',
'user.secure_front' => 'Permitir acesso público à frente - Aplicado apenas se uma senha for definida.',
'user.autologin' => 'Permitir o login a partir de um URL específico. Qualquer pessoa com o link pode fazer o login.',
'url' => 'URL',
'title' => 'Título',
'delete' => 'Apagar',
'optional' => 'Opcional',
'restore' => 'Restaurar',
'export' => 'Exportar',
'import' => 'Importar',
'alert.success.item_created' => 'Item criado com sucesso',
'alert.success.item_updated' => 'Item atualizado com sucesso',
'alert.success.item_deleted' => 'Item apagado com sucesso',
'alert.success.item_restored' => 'Item restaurado com sucesso',
'alert.success.tag_created' => 'Tag criada com sucesso',
'alert.success.tag_updated' => 'Tag atualizada com sucesso',
'alert.success.tag_deleted' => 'Tag apagada com sucesso',
'alert.success.tag_restored' => 'Tag restaurada com sucesso',
'alert.success.updating'=> 'Atualizando lista de apps',
'alert.success.setting_updated' => 'Você editou com sucesso essa configuração',
'alert.error.not_exist' => 'Essa configuração não existe.',
'alert.success.updating' => 'Atualizando lista de Apps',
'alert.success.user_created' => 'Usuário criado com sucesso',
'alert.success.user_updated' => 'Usuário atualizado com sucesso',
'alert.success.user_deleted' => 'Usuário excluído com sucesso',
'alert.success.user_restored' => 'Usuário restaurado com sucesso',
];
+108
View File
@@ -0,0 +1,108 @@
<?php
return array (
'settings.system' => 'Systém',
'settings.appearance' => 'Vzhled',
'settings.miscellaneous' => 'Různé',
'settings.advanced' => 'Rozšířené nastavení',
'settings.support' => 'Podpora',
'settings.donate' => 'Podpořte nás',
'settings.version' => 'Verze',
'settings.background_image' => 'Obrázek pozadí',
'settings.trianglify' => 'Trianglify',
'settings.trianglify_seed' => 'Trianglify Random Seed',
'settings.window_target' => 'Odkazy otevírat v',
'settings.window_target.current' => 'Otevřít v této záložce',
'settings.window_target.one' => 'Otevřít ve stejné záložce',
'settings.window_target.new' => 'Otevřít v nové záložce',
'settings.homepage_search' => 'Vyhledávání na domovské stránce',
'settings.search_provider' => 'Vyhledávat pomocí',
'settings.language' => 'Jazyk',
'settings.reset' => 'Obnovit výchozí nastavení',
'settings.remove' => 'Odstranit',
'settings.search' => 'hledat',
'settings.no_items' => 'Žadné položky nenalezeny',
'settings.label' => 'Název',
'settings.value' => 'Hodnota',
'settings.edit' => 'Upravit',
'settings.view' => 'Náhled',
'settings.custom_css' => 'Vlastní CSS',
'settings.custom_js' => 'Vlastní JavaScript',
'options.none' => '- nenastaveno -',
'options.google' => 'Google',
'options.ddg' => 'DuckDuckGo',
'options.bing' => 'Bing',
'options.qwant' => 'Qwant',
'options.startpage' => 'StartPage',
'options.yes' => 'Ano',
'options.no' => 'Ne',
'options.nzbhydra' => 'NZBHydra',
'options.jackett' => 'Jackett',
'buttons.save' => 'Uložit',
'buttons.cancel' => 'Zrušit',
'buttons.add' => 'Přidat',
'buttons.upload' => 'Nahrát ikonu',
'buttons.downloadapps' => 'Aktualizovat seznam aplikací',
'dash.pin_item' => 'Připnout na dashboard',
'dash.no_apps' => 'Aktuálně nemáte žádné připnuté aplikace, :link1 nebo :link2',
'dash.link1' => 'Přidejte zde aplikacei',
'dash.link2' => 'Připnout na dashboard',
'dash.pinned_items' => 'Připnuté položky',
'apps.app_list' => 'Seznam aplikací',
'apps.view_trash' => 'Zobrazit koš',
'apps.add_application' => 'Přidat aplikaci',
'apps.application_name' => 'Název aplikace',
'apps.colour' => 'Barva',
'apps.icon' => 'Ikona',
'apps.pinned' => 'Připnuto',
'apps.title' => 'Název',
'apps.hex' => 'Hex barva',
'apps.username' => 'Uživatelské jméno',
'apps.password' => 'Heslo',
'apps.config' => 'Config',
'apps.apikey' => 'API Klíč',
'apps.enable' => 'Povolit',
'apps.tag_list' => 'Seznam tagů',
'apps.add_tag' => 'Přidat tag',
'apps.tag_name' => 'Název tagu',
'apps.tags' => 'Tagy',
'apps.override' => 'Pokud je různá od hlavní url',
'apps.preview' => 'Náhled',
'apps.apptype' => 'Typ apliakce',
'apps.website' => 'Webová stránka',
'apps.description' => 'Popis',
'apps.only_admin_account' => 'Pouze pokud máte administrátorský účet!',
'apps.autologin_url' => 'URL automatického přihlášení',
'apps.show_deleted' => 'Zobrazit smazané aplikace',
'dashboard' => 'Domácí obrazovka',
'user.user_list' => 'Uživatelé',
'user.add_user' => 'Přidat uživatele',
'user.username' => 'Uživatelské jméno',
'user.avatar' => 'Avatar',
'user.email' => 'Email',
'user.password_confirm' => 'Potvrdit heslo',
'user.secure_front' => 'Povolit veřejný přístup k rozhraní - Nastavte pouze pokud je nastaveno heslo.',
'user.autologin' => 'Povolit přihlášení ze specifické URL. Kdokoliv s odkazem se může přihlásit.',
'url' => 'URL',
'title' => 'Název',
'delete' => 'Smazat',
'optional' => 'Volitelné',
'restore' => 'Obnovit',
'alert.success.item_created' => 'Položka úspěšně vytvořena',
'alert.success.item_updated' => 'Položka úspěšně aktualizována',
'alert.success.item_deleted' => 'Položka úspěšně smazána',
'alert.success.item_restored' => 'Položka úspěšně obnovena',
'alert.success.updating' => 'Aktualizuji seznam aplikací',
'alert.success.tag_created' => 'Tag úspěšně vytvořen',
'alert.success.tag_updated' => 'Tag úspěšně aktualizován',
'alert.success.tag_deleted' => 'Tag úspěšně smazán',
'alert.success.tag_restored' => 'Tag úspěšně obnoven',
'alert.success.setting_updated' => 'Úspěšně jste aktualizovali nastavení',
'alert.error.not_exist' => 'Tohle nastavení neexistuje.',
'alert.success.user_created' => 'Uživatel úspěšně vytovřen',
'alert.success.user_updated' => 'Uživatel úspěšně aktualizován',
'alert.success.user_deleted' => 'Uživatel úspěšně smazán',
'alert.success.user_restored' => 'Uživatel úspěšně obnoven',
'dashboard.reorder' => 'Změňte pořadí a připněte položky',
'dashboard.settings' => 'Nastavení',
);
+6
View File
@@ -0,0 +1,6 @@
<?php
return array (
'failed' => 'Zadané údaje se neshodují s našimi záznamy.',
'throttle' => 'Příliš mnoho pokusů o přihlášení. Prosím opakujte za :seconds sekund.',
);
+6
View File
@@ -0,0 +1,6 @@
<?php
return array (
'previous' => '&laquo; Předchozí',
'next' => 'Další &raquo;',
);
+9
View File
@@ -0,0 +1,9 @@
<?php
return array (
'password' => 'Heslo musí mít alespoň šest znaků a musí se shodovat s potvrzením.',
'reset' => 'Vaše heslo bylo úspěšně resetováno!',
'sent' => 'Odeslali jsme vám emailem odkaz pro reset hesla!',
'token' => 'Token pro obnovu hesla je neplatný.',
'user' => 'Nenalezli jsme uživatele se zadaným e-mailem.',
);
+121
View File
@@ -0,0 +1,121 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => ':attribute musí být přijat.',
'active_url' => ':attribute není platná URL.',
'after' => ':attribute musí být datum po :date.',
'after_or_equal' => ':attribute musí být datum po nebo rovno :date.',
'alpha' => ':attribute může obsahovat pouze písmena.',
'alpha_dash' => ':attribute může obsahovat pouze písmena, čísla a pomlčku.',
'alpha_num' => ':attribute může obsahovat pouze písmena a čísla.',
'array' => ':attribute musí být pole.',
'before' => ':attribute musí být datum před :date.',
'before_or_equal' => ':attribute musí být datum před nebo rovno :date.',
'between' => [
'numeric' => ':attribute musí být mezi :min a :max.',
'file' => ':attribute musí být mezi :min a :max kilobyty.',
'string' => ':attribute musí mít mezi :min a :max znaky.',
'array' => ':attribute musí mít mezi :min a :max položkami.',
],
'boolean' => ':attribute může být true nebo false.',
'confirmed' => ':attribute potvrzení se neshoduje.',
'date' => ':attribute není platné datum.',
'date_format' => ':attribute neodpovídá formátu :format.',
'different' => ':attribute a :other se musí lišit.',
'digits' => ':attribute musí být :digits číslo.',
'digits_between' => ':attribute must be between :min and :max digits.',
'dimensions' => ':attribute má neplatné rozměry.',
'distinct' => ':attribute položka obsahuje duplicitní hodnoty.',
'email' => ':attribute musí být platná emailová adresa.',
'exists' => 'Vybraný :attribute je neplatný.',
'file' => ':attribute musí být soubor.',
'filled' => ':attribute položka musí mít hodnotu.',
'image' => ':attribute musí být obrázek.',
'in' => 'Vybraný :attribute je neplatný.',
'in_array' => ':attribute položka neexistuje v :other.',
'integer' => ':attribute musí být celočíselný.',
'ip' => ':attribute musí být platná IP adresa.',
'ipv4' => ':attribute musí být platná IPv4 adresa.',
'ipv6' => ':attribute musí být platná IPv6 adresa.',
'json' => ':attribute musí být validní JSON řetězec.',
'max' => [
'numeric' => ':attribute nemůže být větší než :max.',
'file' => ':attribute nemůže být větší než :max kilobytů.',
'string' => ':attribute nemůže být větší než :max znaků.',
'array' => ':attribute nemsí mít více než :max položek.',
],
'mimes' => ':attribute musí být soubor typu: :values.',
'mimetypes' => ':attribute musí být soubor typu: :values.',
'min' => [
'numeric' => ':attribute musí být nejméně :min.',
'file' => ':attribute musí mít nejméně :min kilobytů.',
'string' => ':attribute musí mít alespoň :min znaků.',
'array' => ':attribute musí mít nejméně :min položek.',
],
'not_in' => 'Vybraný :attribute je neplatný.',
'numeric' => ':attribute musí být číslo.',
'present' => ':attribute musí být přitomná.',
'regex' => ':attribute formát je neplatný.',
'required' => ':attribute je povinná.',
'required_if' => ':attribute je poviná pokud :other je :value.',
'required_unless' => ':attribute je poviná pokud :other je v :values.',
'required_with' => ':attribute je poviná pokud :values je přítomna.',
'required_with_all' => ':attribute je poviná pokud :values je přítomna.',
'required_without' => ':attribute je poviná pokud :values není přítomna.',
'required_without_all' => ':attribute je poviná pokud žádná z :values není přítomná.',
'same' => ':attribute a :other musí být stejné.',
'size' => [
'numeric' => ':attribute musí být :size.',
'file' => ':attribute musí být :size kilobytes.',
'string' => ':attribute musí být :size characters.',
'array' => ':attribute musí obsahovat :size items.',
],
'string' => ':attribute musí být řetězec.',
'timezone' => ':attribute musí být pltná časová zóna.',
'unique' => ':attribute musí být unikátní.',
'uploaded' => ':attribute se nepodařilo nahrát.',
'url' => ':attribute formát je neplatný.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => [],
];

Some files were not shown because too many files have changed in this diff Show More