├── l10n ├── .gitkeep ├── kab.json ├── an.json ├── ur_PK.json ├── kab.js ├── an.js ├── ur_PK.js ├── gd.json ├── km.json ├── gd.js ├── ta.json ├── ms_MY.json ├── lb.json ├── nn_NO.json ├── km.js ├── ta.js ├── ms_MY.js ├── uz.json ├── bs.json ├── hy.json ├── lb.js ├── nn_NO.js ├── uz.js ├── hy.js ├── bs.js ├── cy_GB.json ├── cy_GB.js ├── sr@latin.json ├── sr@latin.js ├── vi.json ├── bn_BD.json ├── si.json ├── az.json ├── bn_BD.js ├── si.js ├── vi.js ├── ia.json ├── az.js ├── kn.json ├── ia.js ├── kn.js ├── br.json ├── br.js ├── oc.json ├── oc.js ├── id.json ├── lv.json ├── pt_PT.json ├── id.js ├── lv.js ├── pt_PT.js ├── th.json ├── th.js ├── af.json ├── be.json ├── af.js ├── be.js ├── mn.json ├── mn.js ├── sq.json ├── sq.js ├── ro.json ├── ro.js ├── ko.json ├── ko.js ├── ka_GE.json ├── ka_GE.js ├── es_HN.json ├── es_PA.json ├── es_PE.json ├── es_PR.json ├── es_PY.json ├── es_UY.json ├── es_419.json ├── es_NI.json ├── es_419.js ├── es_HN.js ├── es_NI.js ├── es_PA.js ├── es_PE.js ├── es_PR.js ├── es_PY.js └── es_UY.js ├── .eslintrc.js ├── docs ├── page-sample.png ├── admin-settings.png ├── menu-and-settings-integration.png ├── admin-settings.png.license ├── page-sample.png.license ├── menu-and-settings-integration.png.license └── jwt-sample.php ├── babel.config.js ├── .gitignore ├── vendor-bin ├── mozart │ └── composer.json ├── psalm │ └── composer.json ├── phpunit │ └── composer.json └── csfixer │ └── composer.json ├── js ├── quota-personal.js ├── templates │ ├── icon.handlebars │ └── site.handlebars └── external.js ├── .tx └── config ├── tests ├── psalm-baseline.xml ├── bootstrap.php ├── phpunit.xml └── stub.phpstub ├── lib ├── Exceptions │ ├── GroupNotFoundException.php │ ├── IconNotFoundException.php │ ├── InvalidNameException.php │ ├── InvalidTypeException.php │ ├── InvalidURLException.php │ ├── SiteNotFoundException.php │ ├── InvalidDeviceException.php │ └── LanguageNotFoundException.php ├── Capabilities.php ├── Settings │ ├── Section.php │ ├── Admin.php │ └── Personal.php ├── Migration │ ├── JWTTokenPrivateKeySensitive.php │ └── CopyDefaultIcons.php ├── AppInfo │ └── Application.php └── Controller │ └── SiteController.php ├── templates ├── quota.php ├── frame.php └── settings.php ├── webpack.config.js ├── .php-cs-fixer.dist.php ├── .github ├── workflows │ ├── reuse.yml │ ├── lint-info-xml.yml │ ├── node-when-unrelated.yml │ ├── phpunit-summary-when-unrelated.yml │ ├── dependabot-approve-merge.yml │ ├── lint-php-cs.yml │ ├── psalm.yml │ ├── lint-php.yml │ ├── pr-feedback.yml │ └── node.yml ├── dependabot.yml ├── contributing.md └── issue_template.md ├── psalm.xml ├── LICENSES └── MIT.txt ├── REUSE.toml ├── src └── quota-files-sidebar.js ├── package.json ├── appinfo ├── routes.php └── info.xml ├── composer.json ├── img ├── external.svg ├── settings.svg ├── external-dark.svg └── settings-dark.svg ├── css └── style.css ├── Makefile └── README.md /l10n/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | '@nextcloud', 4 | ], 5 | } 6 | -------------------------------------------------------------------------------- /docs/page-sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/external/HEAD/docs/page-sample.png -------------------------------------------------------------------------------- /docs/admin-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/external/HEAD/docs/admin-settings.png -------------------------------------------------------------------------------- /docs/menu-and-settings-integration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/external/HEAD/docs/menu-and-settings-integration.png -------------------------------------------------------------------------------- /docs/admin-settings.png.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2017 Joas Schilling 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /docs/page-sample.png.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2017 Joas Schilling 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | modules: false, 7 | }, 8 | ], 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /docs/menu-and-settings-integration.png.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2017 Joas Schilling 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude build stuff 2 | build 3 | 4 | # Node 5 | /node_modules 6 | /js/dist 7 | /vendor 8 | /vendor-bin/*/vendor 9 | /lib/Vendor 10 | .php-cs-fixer.cache 11 | -------------------------------------------------------------------------------- /l10n/kab.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Name" : "Nom", 3 | "URL" : "URL", 4 | "Groups" : "Igrawen", 5 | "Uploading…" : "Asali …" 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /l10n/an.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Name" : "Nombre", 3 | "Language" : "Luenga", 4 | "Groups" : "Grupos", 5 | "Uploading…" : "Puyando..." 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /vendor-bin/mozart/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "8.0" 5 | }, 6 | "sort-packages": true 7 | }, 8 | "require": { 9 | "coenjacobs/mozart": "^0.7.1" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vendor-bin/psalm/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "8.0" 5 | }, 6 | "sort-packages": true 7 | }, 8 | "require-dev": { 9 | "vimeo/psalm": "^5.1.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /js/quota-personal.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | var $quotaLink = $('#quota_link'), 3 | $quotaBox = $('#quota'); 4 | 5 | $quotaBox.after($quotaLink); 6 | $quotaLink.removeClass('hidden section'); 7 | }); 8 | -------------------------------------------------------------------------------- /l10n/ur_PK.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "اردو", 3 | "Name" : "اسم", 4 | "URL" : "یو ار ایل", 5 | "Remove site" : "سائٹ ہٹایں" 6 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 7 | } -------------------------------------------------------------------------------- /vendor-bin/phpunit/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "8.0" 5 | }, 6 | "sort-packages": true 7 | }, 8 | "require-dev": { 9 | "phpunit/phpunit": "^9.5" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /l10n/kab.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Name" : "Nom", 5 | "URL" : "URL", 6 | "Groups" : "Igrawen", 7 | "Uploading…" : "Asali …" 8 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /js/templates/icon.handlebars: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 | 4 |
    5 | {{name}} 6 | 7 |
  • 8 | -------------------------------------------------------------------------------- /l10n/an.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Name" : "Nombre", 5 | "Language" : "Luenga", 6 | "Groups" : "Grupos", 7 | "Uploading…" : "Puyando..." 8 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /l10n/ur_PK.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "اردو", 5 | "Name" : "اسم", 6 | "URL" : "یو ار ایل", 7 | "Remove site" : "سائٹ ہٹایں" 8 | }, 9 | "nplurals=2; plural=(n != 1);"); 10 | -------------------------------------------------------------------------------- /l10n/gd.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Name" : "Ainm", 3 | "Uploading…" : "’Ga luchdadh suas…", 4 | "Icons" : "Ìomhaigheagan" 5 | },"pluralForm" :"nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;" 6 | } -------------------------------------------------------------------------------- /l10n/km.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "ភាសាខ្មែរ", 3 | "Name" : "ឈ្មោះ", 4 | "URL" : "URL", 5 | "Language" : "ភាសា", 6 | "Groups" : "ក្រុ", 7 | "Remove site" : "លុប​វេបសាយ" 8 | },"pluralForm" :"nplurals=1; plural=0;" 9 | } -------------------------------------------------------------------------------- /l10n/gd.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Name" : "Ainm", 5 | "Uploading…" : "’Ga luchdadh suas…", 6 | "Icons" : "Ìomhaigheagan" 7 | }, 8 | "nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;"); 9 | -------------------------------------------------------------------------------- /l10n/ta.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "தமிழ்", 3 | "Name" : "பெயர்", 4 | "URL" : "URL", 5 | "Language" : "மொழி", 6 | "Groups" : "குழுக்கள்", 7 | "Remove site" : "தளத்தை அகற்றுக" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /vendor-bin/csfixer/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "platform": { 4 | "php": "8.0" 5 | }, 6 | "sort-packages": true 7 | }, 8 | "require-dev": { 9 | "friendsofphp/php-cs-fixer": "^3.10", 10 | "nextcloud/coding-standard": "^1.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /l10n/ms_MY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Bahasa Melayu", 3 | "Name" : "Nama", 4 | "URL" : "URL", 5 | "Language" : "Bahasa", 6 | "Groups" : "Kumpulan", 7 | "Remove site" : "Buang laman" 8 | },"pluralForm" :"nplurals=1; plural=0;" 9 | } -------------------------------------------------------------------------------- /l10n/lb.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Lëtzebuergesch", 3 | "Name" : "Numm", 4 | "URL" : "URL", 5 | "Language" : "Sprooch", 6 | "Groups" : "Gruppen", 7 | "Remove site" : "Site läschen" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/nn_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Nynorsk", 3 | "Name" : "Namn", 4 | "URL" : "Nettstad", 5 | "Language" : "Språk", 6 | "Groups" : "Grupper", 7 | "Remove site" : "Fjern nettstad" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/km.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "ភាសាខ្មែរ", 5 | "Name" : "ឈ្មោះ", 6 | "URL" : "URL", 7 | "Language" : "ភាសា", 8 | "Groups" : "ក្រុ", 9 | "Remove site" : "លុប​វេបសាយ" 10 | }, 11 | "nplurals=1; plural=0;"); 12 | -------------------------------------------------------------------------------- /l10n/ta.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "தமிழ்", 5 | "Name" : "பெயர்", 6 | "URL" : "URL", 7 | "Language" : "மொழி", 8 | "Groups" : "குழுக்கள்", 9 | "Remove site" : "தளத்தை அகற்றுக" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/ms_MY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Bahasa Melayu", 5 | "Name" : "Nama", 6 | "URL" : "URL", 7 | "Language" : "Bahasa", 8 | "Groups" : "Kumpulan", 9 | "Remove site" : "Buang laman" 10 | }, 11 | "nplurals=1; plural=0;"); 12 | -------------------------------------------------------------------------------- /l10n/uz.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "All languages" : "All languages", 3 | "Name" : "Name", 4 | "URL" : "URL", 5 | "Language" : "Language", 6 | "Groups" : "Groups", 7 | "Uploading…" : "Uploading…", 8 | "Icons" : "Belgilar" 9 | },"pluralForm" :"nplurals=1; plural=0;" 10 | } -------------------------------------------------------------------------------- /l10n/bs.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Bosanski jezik", 3 | "Name" : "Ime", 4 | "URL" : "Url", 5 | "Language" : "Jezik", 6 | "Groups" : "Grupe" 7 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 8 | } -------------------------------------------------------------------------------- /l10n/hy.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Հայերեն", 3 | "Name" : "Անուն", 4 | "URL" : "URL", 5 | "Language" : "Լեզու", 6 | "Groups" : "Խմբեր", 7 | "Remove site" : "Ջնջել կայքը", 8 | "Icons" : "լոգոտիպներ" 9 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 10 | } -------------------------------------------------------------------------------- /l10n/lb.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Lëtzebuergesch", 5 | "Name" : "Numm", 6 | "URL" : "URL", 7 | "Language" : "Sprooch", 8 | "Groups" : "Gruppen", 9 | "Remove site" : "Site läschen" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/nn_NO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Nynorsk", 5 | "Name" : "Namn", 6 | "URL" : "Nettstad", 7 | "Language" : "Språk", 8 | "Groups" : "Grupper", 9 | "Remove site" : "Fjern nettstad" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/uz.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "All languages" : "All languages", 5 | "Name" : "Name", 6 | "URL" : "URL", 7 | "Language" : "Language", 8 | "Groups" : "Groups", 9 | "Uploading…" : "Uploading…", 10 | "Icons" : "Belgilar" 11 | }, 12 | "nplurals=1; plural=0;"); 13 | -------------------------------------------------------------------------------- /l10n/hy.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Հայերեն", 5 | "Name" : "Անուն", 6 | "URL" : "URL", 7 | "Language" : "Լեզու", 8 | "Groups" : "Խմբեր", 9 | "Remove site" : "Ջնջել կայքը", 10 | "Icons" : "լոգոտիպներ" 11 | }, 12 | "nplurals=2; plural=(n != 1);"); 13 | -------------------------------------------------------------------------------- /l10n/bs.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Bosanski jezik", 5 | "Name" : "Ime", 6 | "URL" : "Url", 7 | "Language" : "Jezik", 8 | "Groups" : "Grupe" 9 | }, 10 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 11 | -------------------------------------------------------------------------------- /l10n/cy_GB.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Name" : "Enw", 3 | "URL" : "URL", 4 | "Language" : "Iaith", 5 | "Groups" : "Grwpiau", 6 | "Redirect" : "Ailgyfeirio", 7 | "Remove site" : "Gwaredu safle", 8 | "Icons" : "Eiconau" 9 | },"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;" 10 | } -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs 4 | 5 | [o:nextcloud:p:nextcloud:r:external] 6 | file_filter = translationfiles//external.po 7 | source_file = translationfiles/templates/external.pot 8 | source_lang = en 9 | type = PO 10 | 11 | -------------------------------------------------------------------------------- /l10n/cy_GB.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Name" : "Enw", 5 | "URL" : "URL", 6 | "Language" : "Iaith", 7 | "Groups" : "Grwpiau", 8 | "Redirect" : "Ailgyfeirio", 9 | "Remove site" : "Gwaredu safle", 10 | "Icons" : "Eiconau" 11 | }, 12 | "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"); 13 | -------------------------------------------------------------------------------- /l10n/sr@latin.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "__language_name__" : "Srpski", 3 | "Name" : "naziv", 4 | "URL" : "Url", 5 | "Language" : "Jezik", 6 | "Groups" : "Grupe", 7 | "Uploading…" : "Otpremam…", 8 | "Icons" : "Ikone" 9 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 10 | } -------------------------------------------------------------------------------- /l10n/sr@latin.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "__language_name__" : "Srpski", 5 | "Name" : "naziv", 6 | "URL" : "Url", 7 | "Language" : "Jezik", 8 | "Groups" : "Grupe", 9 | "Uploading…" : "Otpremam…", 10 | "Icons" : "Ikone" 11 | }, 12 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 13 | -------------------------------------------------------------------------------- /tests/psalm-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | array_keys($fixedSites) 6 | 7 | 8 | $bC !== false 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lib/Exceptions/GroupNotFoundException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class GroupNotFoundException extends \OutOfBoundsException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/IconNotFoundException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class IconNotFoundException extends \OutOfBoundsException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/InvalidNameException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class InvalidNameException extends \UnexpectedValueException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/InvalidTypeException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class InvalidTypeException extends \UnexpectedValueException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/InvalidURLException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class InvalidURLException extends \UnexpectedValueException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/SiteNotFoundException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class SiteNotFoundException extends \OutOfBoundsException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/InvalidDeviceException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class InvalidDeviceException extends \UnexpectedValueException { 14 | } 15 | -------------------------------------------------------------------------------- /lib/Exceptions/LanguageNotFoundException.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Exceptions; 12 | 13 | class LanguageNotFoundException extends \OutOfBoundsException { 14 | } 15 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | addPsr4('Test\\', OC::$SERVERROOT . '/tests/lib/', true); 13 | \OC::$composerAutoloader->addPsr4('Tests\\', OC::$SERVERROOT . '/tests/', true); 14 | 15 | OC_App::loadApp('external'); 16 | 17 | OC_Hook::clear(); 18 | -------------------------------------------------------------------------------- /l10n/vi.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "All languages" : "Tất cả ngôn ngữ", 3 | "No file uploaded" : "Không có tệp nào được tải lên", 4 | "__language_name__" : "Tiếng Việt", 5 | "Name" : "Tên", 6 | "URL" : "URL", 7 | "Language" : "Ngôn ngữ", 8 | "Groups" : "Nhóm", 9 | "Icon" : "Biểu tượng", 10 | "Redirect" : "Chuyển hướng", 11 | "Remove site" : "Xóa URL", 12 | "Uploading…" : "Đang tải lên…", 13 | "Icons" : "Biểu tượng" 14 | },"pluralForm" :"nplurals=1; plural=0;" 15 | } -------------------------------------------------------------------------------- /templates/quota.php: -------------------------------------------------------------------------------- 1 | 4 | * @license GNU AGPL version 3 or any later version 5 | * 6 | * SPDX-FileCopyrightText: 2017 Joas Schilling 7 | * SPDX-License-Identifier: AGPL-3.0-or-later 8 | */ 9 | 10 | script('external', 'quota-personal'); 11 | ?> 12 | 15 | -------------------------------------------------------------------------------- /l10n/bn_BD.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "একটি আইকন নির্বাচন কর", 3 | "__language_name__" : "বাংলা ভাষা", 4 | "Name" : "নাম", 5 | "URL" : "URL", 6 | "Language" : "ভাষা", 7 | "Groups" : "গোষ্ঠীসমূহ", 8 | "Remove site" : "সাইট অপসারণ", 9 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "আরো মনে রাখুন যে নিরাপত্তাজনিত কারণে ইদানিং অনেক সাইট iframing অনুমোদন করেনা" 10 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 11 | } -------------------------------------------------------------------------------- /l10n/si.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "All languages" : "සියලුම භාෂා", 3 | "All devices" : "සියලුම උපාංග", 4 | "Only in the Android app" : "ඇන්ඩ්‍රොයිඩ් යෙදුමේ පමණි", 5 | "The given device is invalid" : "දී ඇති උපාංගය වලංගු නොවේ", 6 | "The site does not exist" : "වියමන අඩවිය නොපවතී", 7 | "__language_name__" : "සිංහල", 8 | "Name" : "නම", 9 | "Language" : "භාෂාව", 10 | "Groups" : "සමූහ…", 11 | "Uploading…" : "උඩුගත වෙමින්…" 12 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 13 | } -------------------------------------------------------------------------------- /l10n/az.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "İkonu seç", 3 | "__language_name__" : "Azərbaycan dili", 4 | "Name" : "Ad", 5 | "URL" : "URL", 6 | "Language" : "Dil", 7 | "Groups" : "Qruplar", 8 | "Remove site" : "Saytı sil", 9 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Bundan başqa diqqetli olun ona görə ki, hal-hazırda çoxlu saytlar iframing-i təhlükəsizliyə görə qəbul etmir." 10 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 11 | } -------------------------------------------------------------------------------- /l10n/bn_BD.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "একটি আইকন নির্বাচন কর", 5 | "__language_name__" : "বাংলা ভাষা", 6 | "Name" : "নাম", 7 | "URL" : "URL", 8 | "Language" : "ভাষা", 9 | "Groups" : "গোষ্ঠীসমূহ", 10 | "Remove site" : "সাইট অপসারণ", 11 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "আরো মনে রাখুন যে নিরাপত্তাজনিত কারণে ইদানিং অনেক সাইট iframing অনুমোদন করেনা" 12 | }, 13 | "nplurals=2; plural=(n != 1);"); 14 | -------------------------------------------------------------------------------- /l10n/si.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "All languages" : "සියලුම භාෂා", 5 | "All devices" : "සියලුම උපාංග", 6 | "Only in the Android app" : "ඇන්ඩ්‍රොයිඩ් යෙදුමේ පමණි", 7 | "The given device is invalid" : "දී ඇති උපාංගය වලංගු නොවේ", 8 | "The site does not exist" : "වියමන අඩවිය නොපවතී", 9 | "__language_name__" : "සිංහල", 10 | "Name" : "නම", 11 | "Language" : "භාෂාව", 12 | "Groups" : "සමූහ…", 13 | "Uploading…" : "උඩුගත වෙමින්…" 14 | }, 15 | "nplurals=2; plural=(n != 1);"); 16 | -------------------------------------------------------------------------------- /l10n/vi.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "All languages" : "Tất cả ngôn ngữ", 5 | "No file uploaded" : "Không có tệp nào được tải lên", 6 | "__language_name__" : "Tiếng Việt", 7 | "Name" : "Tên", 8 | "URL" : "URL", 9 | "Language" : "Ngôn ngữ", 10 | "Groups" : "Nhóm", 11 | "Icon" : "Biểu tượng", 12 | "Redirect" : "Chuyển hướng", 13 | "Remove site" : "Xóa URL", 14 | "Uploading…" : "Đang tải lên…", 15 | "Icons" : "Biểu tượng" 16 | }, 17 | "nplurals=1; plural=0;"); 18 | -------------------------------------------------------------------------------- /l10n/ia.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selige un icone", 3 | "__language_name__" : "Interlingua de IALA", 4 | "Name" : "Nomine", 5 | "URL" : "URL", 6 | "Language" : "Lingua", 7 | "Groups" : "Gruppos", 8 | "Remove site" : "Remove sito", 9 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Ulteriormente nota que multe sitos iste dies dishabilita iframing debite a motivationes de securitate." 10 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 11 | } -------------------------------------------------------------------------------- /l10n/az.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "İkonu seç", 5 | "__language_name__" : "Azərbaycan dili", 6 | "Name" : "Ad", 7 | "URL" : "URL", 8 | "Language" : "Dil", 9 | "Groups" : "Qruplar", 10 | "Remove site" : "Saytı sil", 11 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Bundan başqa diqqetli olun ona görə ki, hal-hazırda çoxlu saytlar iframing-i təhlükəsizliyə görə qəbul etmir." 12 | }, 13 | "nplurals=2; plural=(n != 1);"); 14 | -------------------------------------------------------------------------------- /l10n/kn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "ಚಿಹ್ನೆ ಒಂದನ್ನು ಆಯ್ಕೆ ಮಾಡಿ", 3 | "__language_name__" : "ಕನ್ನಡ", 4 | "Name" : "ಹೆಸರು", 5 | "URL" : "ಜಾಲದ ಕೊಂಡಿ", 6 | "Language" : "ಭಾಷೆ", 7 | "Groups" : "ಗುಂಪುಗಳು", 8 | "Remove site" : " ಅಂತರ್ಜಾಲದ ತಾಣವನ್ನು ತೆಗೆದುಹಾಕಿ", 9 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "ಇದಲ್ಲದೆ ಈ ದಿನಗಳಲ್ಲಿ ಭದ್ರತೆ ಕಾರಣಗಳಿಂದಾಗಿ ಅನೇಕ ತಾಣಗಳು IFRAME ಗಳನ್ನು ತಡೆಹಿಡಿಯಬಹುದೆಂದು ಗಮನಿಸಿ." 10 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 11 | } -------------------------------------------------------------------------------- /l10n/ia.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selige un icone", 5 | "__language_name__" : "Interlingua de IALA", 6 | "Name" : "Nomine", 7 | "URL" : "URL", 8 | "Language" : "Lingua", 9 | "Groups" : "Gruppos", 10 | "Remove site" : "Remove sito", 11 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Ulteriormente nota que multe sitos iste dies dishabilita iframing debite a motivationes de securitate." 12 | }, 13 | "nplurals=2; plural=(n != 1);"); 14 | -------------------------------------------------------------------------------- /l10n/kn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "ಚಿಹ್ನೆ ಒಂದನ್ನು ಆಯ್ಕೆ ಮಾಡಿ", 5 | "__language_name__" : "ಕನ್ನಡ", 6 | "Name" : "ಹೆಸರು", 7 | "URL" : "ಜಾಲದ ಕೊಂಡಿ", 8 | "Language" : "ಭಾಷೆ", 9 | "Groups" : "ಗುಂಪುಗಳು", 10 | "Remove site" : " ಅಂತರ್ಜಾಲದ ತಾಣವನ್ನು ತೆಗೆದುಹಾಕಿ", 11 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "ಇದಲ್ಲದೆ ಈ ದಿನಗಳಲ್ಲಿ ಭದ್ರತೆ ಕಾರಣಗಳಿಂದಾಗಿ ಅನೇಕ ತಾಣಗಳು IFRAME ಗಳನ್ನು ತಡೆಹಿಡಿಯಬಹುದೆಂದು ಗಮನಿಸಿ." 12 | }, 13 | "nplurals=2; plural=(n > 1);"); 14 | -------------------------------------------------------------------------------- /templates/frame.php: -------------------------------------------------------------------------------- 1 | 4 | * @author Frank Karlitschek 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2012 Frank Karlitschek 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | script('external', 'external'); 12 | style('external', 'style'); 13 | 14 | /** @var array $_ */ 15 | ?> 16 | 17 | -------------------------------------------------------------------------------- /l10n/br.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "All languages" : "Pep yezh", 3 | "__language_name__" : "Brezhoneg", 4 | "Name" : "Anv", 5 | "URL" : "URL", 6 | "Language" : "Yezh", 7 | "Groups" : "Strolladoù", 8 | "Icon" : "Skeudennig", 9 | "Uploading…" : "O pellkas" 10 | },"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);" 11 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: { 5 | admin: path.join(__dirname, 'src', 'admin.js'), 6 | 'quota-files-sidebar': path.join(__dirname, 'src', 'quota-files-sidebar.js'), 7 | }, 8 | output: { 9 | path: path.join(__dirname, 'js', 'dist'), 10 | }, 11 | devtool: 'source-map', 12 | mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.js$/, 17 | loader: 'babel-loader', 18 | exclude: /node_modules/, 19 | }, 20 | ], 21 | }, 22 | resolve: { 23 | extensions: ['.js', '.vue'], 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /l10n/br.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "All languages" : "Pep yezh", 5 | "__language_name__" : "Brezhoneg", 6 | "Name" : "Anv", 7 | "URL" : "URL", 8 | "Language" : "Yezh", 9 | "Groups" : "Strolladoù", 10 | "Icon" : "Skeudennig", 11 | "Uploading…" : "O pellkas" 12 | }, 13 | "nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"); 14 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | 7 | * @license GNU AGPL version 3 or any later version 8 | * 9 | * SPDX-FileCopyrightText: 2017 Joas Schilling 10 | * SPDX-License-Identifier: AGPL-3.0-or-later 11 | */ 12 | 13 | require_once './vendor-bin/csfixer/vendor/autoload.php'; 14 | 15 | use Nextcloud\CodingStandard\Config; 16 | 17 | $config = new Config(); 18 | $config 19 | ->getFinder() 20 | ->ignoreVCSIgnored(true) 21 | ->notPath('build') 22 | ->notPath('l10n') 23 | ->notPath('src') 24 | ->notPath('vendor') 25 | ->in(__DIR__); 26 | return $config; 27 | -------------------------------------------------------------------------------- /l10n/oc.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Seleccionar una icòna", 3 | "All languages" : "Totas las lengas", 4 | "The given language does not exist" : "La lenga especificada existís pas", 5 | "__language_name__" : "Occitan", 6 | "Name" : "Nom", 7 | "URL" : "URL", 8 | "Language" : "Lenga", 9 | "Groups" : "Gropes", 10 | "Devices" : "Periferics", 11 | "Position" : "Posicion", 12 | "Remove site" : "Suprimir lo site", 13 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "D'una autra costat, notatz que fòrça sites interdison l’utilizacion dels iframes per de rasons de seguretat.", 14 | "Icons" : "Icònas" 15 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 16 | } -------------------------------------------------------------------------------- /l10n/oc.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Seleccionar una icòna", 5 | "All languages" : "Totas las lengas", 6 | "The given language does not exist" : "La lenga especificada existís pas", 7 | "__language_name__" : "Occitan", 8 | "Name" : "Nom", 9 | "URL" : "URL", 10 | "Language" : "Lenga", 11 | "Groups" : "Gropes", 12 | "Devices" : "Periferics", 13 | "Position" : "Posicion", 14 | "Remove site" : "Suprimir lo site", 15 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "D'una autra costat, notatz que fòrça sites interdison l’utilizacion dels iframes per de rasons de seguretat.", 16 | "Icons" : "Icònas" 17 | }, 18 | "nplurals=2; plural=(n > 1);"); 19 | -------------------------------------------------------------------------------- /l10n/id.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Pilih ikon", 3 | "All languages" : "Semua bahasa", 4 | "No file uploaded" : "Tidak ada file diunggah", 5 | "External sites" : "Situs eksternal", 6 | "__language_name__" : "Bahasa Indonesia", 7 | "Name" : "Nama", 8 | "URL" : "URL", 9 | "Language" : "Bahasa", 10 | "Groups" : "Grup", 11 | "Position" : "Posisi", 12 | "Redirect" : "Mengalihkan", 13 | "Remove site" : "Hapus situs", 14 | "Uploading…" : "Menunggah…", 15 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Lebih lanjut perlu diketahui bahwa banyak situs saat ini tidak mengizinkan iframing karena alasan keamanan.", 16 | "Icons" : "Ikon" 17 | },"pluralForm" :"nplurals=1; plural=0;" 18 | } -------------------------------------------------------------------------------- /l10n/lv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Atlasīt ikonu", 3 | "All languages" : "Visas valodas", 4 | "Setting menu" : "Iestatījumu izvēlne", 5 | "User quota" : "Lietotāja apjoms", 6 | "No file uploaded" : "Nav augšupielādēta datne", 7 | "__language_name__" : "Latviešu", 8 | "Name" : "Nosaukums", 9 | "URL" : "URL", 10 | "Language" : "Valoda", 11 | "Groups" : "Grupas", 12 | "Devices" : "Ierīces", 13 | "Icon" : "Ikona", 14 | "Redirect" : "Novirzīt", 15 | "Remove site" : "Noņemt vietni", 16 | "Delete icon" : "Noņemt ikonu", 17 | "Uploading…" : "Augšupielādē...", 18 | "Icons" : "Ikonas", 19 | "Upload new icon" : "Augšupielādēt jaunu ikonu" 20 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" 21 | } -------------------------------------------------------------------------------- /lib/Capabilities.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External; 12 | 13 | use OCP\Capabilities\ICapability; 14 | 15 | /** 16 | * Class Capabilities 17 | * 18 | * @package OCA\External 19 | */ 20 | class Capabilities implements ICapability { 21 | /** 22 | * Return this classes capabilities 23 | */ 24 | public function getCapabilities() { 25 | return [ 26 | 'external' => [ 27 | 'v1' => [ 28 | 'sites', 29 | 'device', 30 | 'groups', 31 | 'redirect', 32 | ], 33 | ], 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /l10n/pt_PT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecione um ícone", 3 | "No file uploaded" : "Nenhum ficheiro carregado", 4 | "__language_name__" : "Português", 5 | "Name" : "Nome", 6 | "URL" : "URL", 7 | "Language" : "Idioma", 8 | "Groups" : "Grupos", 9 | "Position" : "Position", 10 | "Redirect" : "Redirecionar", 11 | "Remove site" : "Remover site", 12 | "New site" : "Novo site", 13 | "Uploading…" : "A enviar…", 14 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Além disso, por favor, note que muitos sites nestes dias desautorizam iframing, por motivos de segurança.", 15 | "Icons" : "Ícones" 16 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 17 | } -------------------------------------------------------------------------------- /l10n/id.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Pilih ikon", 5 | "All languages" : "Semua bahasa", 6 | "No file uploaded" : "Tidak ada file diunggah", 7 | "External sites" : "Situs eksternal", 8 | "__language_name__" : "Bahasa Indonesia", 9 | "Name" : "Nama", 10 | "URL" : "URL", 11 | "Language" : "Bahasa", 12 | "Groups" : "Grup", 13 | "Position" : "Posisi", 14 | "Redirect" : "Mengalihkan", 15 | "Remove site" : "Hapus situs", 16 | "Uploading…" : "Menunggah…", 17 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Lebih lanjut perlu diketahui bahwa banyak situs saat ini tidak mengizinkan iframing karena alasan keamanan.", 18 | "Icons" : "Ikon" 19 | }, 20 | "nplurals=1; plural=0;"); 21 | -------------------------------------------------------------------------------- /l10n/lv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Atlasīt ikonu", 5 | "All languages" : "Visas valodas", 6 | "Setting menu" : "Iestatījumu izvēlne", 7 | "User quota" : "Lietotāja apjoms", 8 | "No file uploaded" : "Nav augšupielādēta datne", 9 | "__language_name__" : "Latviešu", 10 | "Name" : "Nosaukums", 11 | "URL" : "URL", 12 | "Language" : "Valoda", 13 | "Groups" : "Grupas", 14 | "Devices" : "Ierīces", 15 | "Icon" : "Ikona", 16 | "Redirect" : "Novirzīt", 17 | "Remove site" : "Noņemt vietni", 18 | "Delete icon" : "Noņemt ikonu", 19 | "Uploading…" : "Augšupielādē...", 20 | "Icons" : "Ikonas", 21 | "Upload new icon" : "Augšupielādēt jaunu ikonu" 22 | }, 23 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); 24 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | ../ 12 | 13 | 14 | ../tests 15 | 16 | 17 | 18 | 19 | 20 | 21 | . 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /l10n/pt_PT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecione um ícone", 5 | "No file uploaded" : "Nenhum ficheiro carregado", 6 | "__language_name__" : "Português", 7 | "Name" : "Nome", 8 | "URL" : "URL", 9 | "Language" : "Idioma", 10 | "Groups" : "Grupos", 11 | "Position" : "Position", 12 | "Redirect" : "Redirecionar", 13 | "Remove site" : "Remover site", 14 | "New site" : "Novo site", 15 | "Uploading…" : "A enviar…", 16 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Além disso, por favor, note que muitos sites nestes dias desautorizam iframing, por motivos de segurança.", 17 | "Icons" : "Ícones" 18 | }, 19 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 20 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. 7 | # 8 | # SPDX-License-Identifier: CC0-1.0 9 | 10 | name: REUSE Compliance Check 11 | 12 | on: [pull_request] 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | reuse-compliance-check: 19 | runs-on: ubuntu-latest-low 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | with: 24 | persist-credentials: false 25 | 26 | - name: REUSE Compliance Check 27 | uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5.0.0 28 | -------------------------------------------------------------------------------- /tests/stub.phpstub: -------------------------------------------------------------------------------- 1 | 7 | * @author John Molakvoæ 8 | * @author Morris Jobke 9 | * @author Roeland Jago Douma 10 | * @license GNU AGPL version 3 or any later version 11 | * 12 | * SPDX-FileCopyrightText: 2019 John Molakvoæ 13 | * SPDX-FileCopyrightText: 2019 Morris Jobke 14 | * SPDX-FileCopyrightText: 2019 Roeland Jago Douma 15 | * SPDX-License-Identifier: AGPL-3.0-or-later 16 | */ 17 | 18 | namespace OCA\Files\Event; 19 | 20 | use OCP\EventDispatcher\Event; 21 | 22 | class LoadAdditionalScriptsEvent extends Event { 23 | private $hiddenFields = []; 24 | 25 | public function addHiddenField(string $name, string $value): void { 26 | } 27 | 28 | public function getHiddenFields(): array { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /lib/Settings/Section.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Settings; 12 | 13 | use OCP\IL10N; 14 | use OCP\IURLGenerator; 15 | use OCP\Settings\IIconSection; 16 | 17 | class Section implements IIconSection { 18 | private IL10N $l; 19 | private IURLGenerator $url; 20 | 21 | public function __construct(IURLGenerator $url, IL10N $l) { 22 | $this->url = $url; 23 | $this->l = $l; 24 | } 25 | 26 | public function getIcon(): string { 27 | return $this->url->imagePath('external', 'external-dark.svg'); 28 | } 29 | 30 | public function getID(): string { 31 | return 'external'; 32 | } 33 | 34 | public function getName(): string { 35 | return $this->l->t('External sites'); 36 | } 37 | 38 | public function getPriority(): int { 39 | return 55; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /js/external.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | function pageY(elem) { 3 | return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop; 4 | } 5 | 6 | var buffer = 0; //scroll bar buffer 7 | function resizeIframe() { 8 | var height = document.documentElement.clientHeight; 9 | height -= pageY(document.getElementById('ifm')) + buffer; 10 | height = (height < 0) ? 0 : height; 11 | document.getElementById('ifm').style.height = height + 'px'; 12 | } 13 | 14 | document.getElementById('ifm').onload = resizeIframe; 15 | window.onresize = resizeIframe; 16 | resizeIframe(); 17 | // hash routing support 18 | if(window.location.hash && window.location.hash.length) { 19 | updateHash(); 20 | } 21 | 22 | window.addEventListener("hashchange", function(event) { 23 | updateHash(); 24 | }); 25 | 26 | function updateHash() { 27 | const iframeURL = new URL(document.getElementById('ifm').src); 28 | iframeURL.hash = window.location.hash; 29 | document.getElementById('ifm').src = iframeURL.toString(); 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /lib/Migration/JWTTokenPrivateKeySensitive.php: -------------------------------------------------------------------------------- 1 | config->getKeys(Application::APP_ID) as $key) { 29 | if (!str_starts_with($key, 'jwt_token_privkey_')) { 30 | continue; 31 | } 32 | 33 | $secret = $this->config->getValueString(Application::APP_ID, $key); 34 | $this->config->setValueString(Application::APP_ID, $key, $secret, sensitive: true); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /l10n/th.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "เลือกไอคอน", 3 | "All languages" : "ภาษาทั้งหมด", 4 | "Header" : "ส่วนหัว", 5 | "Setting menu" : "เมนูการตั้งค่า", 6 | "User quota" : "โควตาผู้ใช้งาน", 7 | "Public footer" : "ส่วนท้ายสาธารณะ", 8 | "All devices" : "อุปกรณ์ทั้งหมด", 9 | "Only in the Android app" : "เฉพาะในแอป Android", 10 | "Only in the iOS app" : "เฉพาะในแอป iOS", 11 | "Only in the desktop client" : "เฉพาะในไคลเอ็นต์เดสก์ท็อป", 12 | "Only in the browser" : "เฉพาะในเบราว์เซอร์", 13 | "External sites" : "เว็บไซต์ภายนอก", 14 | "__language_name__" : "ไทย", 15 | "Name" : "ชื่อ", 16 | "URL" : "URL", 17 | "Language" : "ภาษา", 18 | "Groups" : "กลุ่ม", 19 | "Devices" : "อุปกรณ์", 20 | "Icon" : "ไอคอน", 21 | "Position" : "ตำแหน่ง", 22 | "Redirect" : "เปลี่ยนเส้นทาง", 23 | "Remove site" : "ลบเว็บไซต์ออก", 24 | "Uploading…" : "กำลังอัปโหลด…", 25 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "นอกจากนี้โปรดทราบว่าหลายเว็บไซต์ในปัจจุบันไม่อนุญาตให้ใช้ iframe เนื่องจากเหตุผลด้านความปลอดภัย", 26 | "Icons" : "ไอคอน", 27 | "Upload new icon" : "อัปโหลดไอคอนใหม่" 28 | },"pluralForm" :"nplurals=1; plural=0;" 29 | } -------------------------------------------------------------------------------- /l10n/th.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "เลือกไอคอน", 5 | "All languages" : "ภาษาทั้งหมด", 6 | "Header" : "ส่วนหัว", 7 | "Setting menu" : "เมนูการตั้งค่า", 8 | "User quota" : "โควตาผู้ใช้งาน", 9 | "Public footer" : "ส่วนท้ายสาธารณะ", 10 | "All devices" : "อุปกรณ์ทั้งหมด", 11 | "Only in the Android app" : "เฉพาะในแอป Android", 12 | "Only in the iOS app" : "เฉพาะในแอป iOS", 13 | "Only in the desktop client" : "เฉพาะในไคลเอ็นต์เดสก์ท็อป", 14 | "Only in the browser" : "เฉพาะในเบราว์เซอร์", 15 | "External sites" : "เว็บไซต์ภายนอก", 16 | "__language_name__" : "ไทย", 17 | "Name" : "ชื่อ", 18 | "URL" : "URL", 19 | "Language" : "ภาษา", 20 | "Groups" : "กลุ่ม", 21 | "Devices" : "อุปกรณ์", 22 | "Icon" : "ไอคอน", 23 | "Position" : "ตำแหน่ง", 24 | "Redirect" : "เปลี่ยนเส้นทาง", 25 | "Remove site" : "ลบเว็บไซต์ออก", 26 | "Uploading…" : "กำลังอัปโหลด…", 27 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "นอกจากนี้โปรดทราบว่าหลายเว็บไซต์ในปัจจุบันไม่อนุญาตให้ใช้ iframe เนื่องจากเหตุผลด้านความปลอดภัย", 28 | "Icons" : "ไอคอน", 29 | "Upload new icon" : "อัปโหลดไอคอนใหม่" 30 | }, 31 | "nplurals=1; plural=0;"); 32 | -------------------------------------------------------------------------------- /.github/workflows/lint-info-xml.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint info.xml 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-info-xml-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | xml-linters: 22 | runs-on: ubuntu-latest-low 23 | 24 | name: info.xml lint 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Download schema 32 | run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd 33 | 34 | - name: Lint info.xml 35 | uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2 36 | with: 37 | xml-file: ./appinfo/info.xml 38 | xml-schema-file: ./info.xsd 39 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | version = 1 4 | SPDX-PackageName = "external" 5 | SPDX-PackageSupplier = "Nextcloud " 6 | SPDX-PackageDownloadLocation = "https://github.com/nextcloud/external" 7 | 8 | [[annotations]] 9 | path = [".github/**", ".editorconfig", "babel.config.js", ".php-cs-fixer.dist.php", "package-lock.json", "package.json", "composer.json", "composer.lock", "README.md", "img/app-dark.svg", "img/app.svg", "webpack.js", "stylelint.config.js", ".eslintrc.js", ".gitignore", ".jshintrc", ".l10nignore", "action/.gitignore", "action/package.json", "action/package-lock.json", "action/dist/index.js", "tests/**", "psalm.xml", "vendor-bin/**/composer.json", "vendor-bin/**/composer.lock", ".tx/config", "webpack.config.js"] 10 | precedence = "aggregate" 11 | SPDX-FileCopyrightText = "none" 12 | SPDX-License-Identifier = "CC0-1.0" 13 | 14 | [[annotations]] 15 | path = ["l10n/**.js", "l10n/**.json", "js/**.js.map", "js/**.js", "js/templates/**.handlebars", "img/external-dark.svg", "img/external.svg", "img/settings-dark.svg", "img/settings.svg"] 16 | precedence = "aggregate" 17 | SPDX-FileCopyrightText = "2017-2024 Nextcloud contributors" 18 | SPDX-License-Identifier = "AGPL-3.0-or-later" 19 | -------------------------------------------------------------------------------- /src/quota-files-sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @copyright Copyright (c) 2023 Kate 3 | * @license GNU AGPL version 3 or any later version 4 | * 5 | * SPDX-FileCopyrightText: 2023 Kate 6 | * SPDX-License-Identifier: AGPL-3.0-or-later 7 | */ 8 | 9 | import {loadState} from '@nextcloud/initial-state' 10 | 11 | document.addEventListener('DOMContentLoaded', () => { 12 | const state = loadState('external', 'external-quota-sites') 13 | 14 | for (const site of state) { 15 | const image = document.createElement('img') 16 | image.src = site.image 17 | 18 | const icon = document.createElement('div') 19 | icon.classList.add('app-navigation-entry-icon') 20 | icon.append(image) 21 | 22 | const name = document.createElement('span') 23 | name.classList.add('app-navigation-entry__name') 24 | name.innerText = site.name 25 | 26 | const a = document.createElement('a') 27 | a.classList.add('app-navigation-entry-link') 28 | a.href = site.href 29 | a.append(icon) 30 | a.append(name) 31 | 32 | const div = document.createElement('div') 33 | div.classList.add('app-navigation-entry') 34 | div.append(a) 35 | 36 | const li = document.createElement('li') 37 | li.append(div) 38 | 39 | document.getElementsByClassName('app-navigation-entry__settings')[0].prepend(li) 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /.github/workflows/node-when-unrelated.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # Use node together with node-when-unrelated to make eslint a required check for GitHub actions 7 | # https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks 8 | 9 | name: Node 10 | 11 | on: 12 | pull_request: 13 | paths-ignore: 14 | - '.github/workflows/**' 15 | - 'src/**' 16 | - 'appinfo/info.xml' 17 | - 'package.json' 18 | - 'package-lock.json' 19 | - 'tsconfig.json' 20 | - '**.js' 21 | - '**.ts' 22 | - '**.vue' 23 | push: 24 | branches: 25 | - main 26 | - master 27 | - stable* 28 | 29 | concurrency: 30 | group: node-${{ github.head_ref || github.run_id }} 31 | cancel-in-progress: true 32 | 33 | jobs: 34 | build: 35 | permissions: 36 | contents: none 37 | 38 | runs-on: ubuntu-latest 39 | 40 | name: node 41 | steps: 42 | - name: Skip 43 | run: 'echo "No JS/TS files changed, skipped Node"' 44 | -------------------------------------------------------------------------------- /lib/Settings/Admin.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Settings; 12 | 13 | use OCP\AppFramework\Http\TemplateResponse; 14 | use OCP\IURLGenerator; 15 | use OCP\Settings\ISettings; 16 | 17 | class Admin implements ISettings { 18 | /** @var IURLGenerator */ 19 | protected $url; 20 | 21 | public function __construct(IURLGenerator $url) { 22 | $this->url = $url; 23 | } 24 | 25 | /** 26 | * @return TemplateResponse 27 | */ 28 | public function getForm() { 29 | return new TemplateResponse('external', 'settings', [], 'blank'); 30 | } 31 | 32 | /** 33 | * @return string the section ID, e.g. 'sharing' 34 | */ 35 | public function getSection() { 36 | return 'external'; 37 | } 38 | 39 | /** 40 | * @return int whether the form should be rather on the top or bottom of 41 | * the admin section. The forms are arranged in ascending order of the 42 | * priority values. It is required to return a value between 0 and 100. 43 | * 44 | * E.g.: 70 45 | */ 46 | public function getPriority() { 47 | return 55; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "external", 3 | "version": "8.0.0-dev.0", 4 | "private": true, 5 | "description": "", 6 | "author": "Joas Schilling ", 7 | "scripts": { 8 | "test:unit": "echo \"Error: no test specified\" && exit 1", 9 | "lint": "eslint --ext .js,.vue src", 10 | "lint:fix": "eslint --ext .js,.vue src --fix", 11 | "build": "NODE_ENV=production webpack --progress --config webpack.config.js", 12 | "dev": "NODE_ENV=development webpack --progress --config webpack.config.js", 13 | "watch": "NODE_ENV=development webpack --progress --watch --config webpack.config.js" 14 | }, 15 | "dependencies": { 16 | "@nextcloud/initial-state": "^3.0.0", 17 | "@nextcloud/router": "^3.1.0", 18 | "escape-html": "^1.0.3" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.28.5", 22 | "@babel/preset-env": "^7.28.5", 23 | "@nextcloud/browserslist-config": "^3.1.2", 24 | "@nextcloud/eslint-config": "^8.4.2", 25 | "@nextcloud/eslint-plugin": "^2.2.1", 26 | "babel-eslint": "^10.1.0", 27 | "babel-loader": "^10.0.0", 28 | "webpack": "^5.103.0", 29 | "webpack-cli": "^6.0.1" 30 | }, 31 | "browserslist": [ 32 | "extends @nextcloud/browserslist-config" 33 | ], 34 | "engines": { 35 | "node": "^24.0.0", 36 | "npm": "^11.3.0" 37 | }, 38 | "license": "AGPL-3.0-or-later" 39 | } 40 | -------------------------------------------------------------------------------- /l10n/af.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Kies ’n ikoon", 3 | "All languages" : "Alle tale", 4 | "All devices" : "Alle toestelle", 5 | "Only in the Android app" : "Slegs in die Android-toep", 6 | "Only in the iOS app" : "Slegs in die iOS-toep", 7 | "Only in the desktop client" : "Slegs in die werkskermkliënt", 8 | "Only in the browser" : "Slegs in die blaaier", 9 | "The given label is invalid" : "Die gegewe etiket is ongeldig", 10 | "The given URL is invalid" : "Die gegewe bronadres is ongeldig", 11 | "The given language does not exist" : "Die gegewe taal bestaan nie", 12 | "The given type is invalid" : "Die gegewe tipe is ongeldig", 13 | "The given device is invalid" : "Die gegewe toestel is ongeldig", 14 | "The given icon does not exist" : "Die gegewe ikoon bestaan nie", 15 | "The site does not exist" : "Die werf bestaan nie", 16 | "No file uploaded" : "Geen lêer opgelaai", 17 | "External sites" : "Eksterne werwe", 18 | "__language_name__" : "Afrikaans", 19 | "Name" : "Naam", 20 | "URL" : "Bronadres", 21 | "Language" : "Taal", 22 | "Groups" : "Groepe", 23 | "Devices" : "Toestelle", 24 | "Icon" : "Ikoon", 25 | "Position" : "Posisie", 26 | "Redirect" : "Herverwys", 27 | "Remove site" : "Verwyder werf", 28 | "New site" : "Nuwe werf" 29 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 30 | } -------------------------------------------------------------------------------- /l10n/be.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Выберыце значок", 3 | "All languages" : "Усе мовы", 4 | "User quota" : "Квота карыстальніка", 5 | "All devices" : "Усе прылады", 6 | "The given language does not exist" : "Гэта мова не існуе", 7 | "__language_name__" : "Беларуская", 8 | "Name" : "Назва", 9 | "URL" : "URL-адрас", 10 | "Language" : "Мова", 11 | "Groups" : "Групы", 12 | "Devices" : "Прылады", 13 | "Icon" : "Значок", 14 | "Delete icon" : "Выдаліць значок", 15 | "Uploading…" : "Запампоўванне…", 16 | "Reloading icon list…" : "Перазагрузка спісу значкоў…", 17 | "Icon could not be uploaded" : "Не ўдалося запампаваць значок", 18 | "A JSON Web Token containing user´s email, uid and display name in its payload can be embedded into the link using the {jwt} placeholder. See the {linkstart}documentation{linkend} how to decode it." : "JSON-токен, які змяшчае адрас электроннай пошты, UID і імя карыстальніка ў сваёй карыснай нагрузцы, можа быць убудаваны ў спасылку з дапамогай запаўняльніка {jwt}. Паглядзіце ў {linkstart}дакументацыі{linkend}, як яго расшыфраваць.", 19 | "Icons" : "Значкі", 20 | "Upload new icon" : "Запампаваць новы значок" 21 | },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" 22 | } -------------------------------------------------------------------------------- /l10n/af.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Kies ’n ikoon", 5 | "All languages" : "Alle tale", 6 | "All devices" : "Alle toestelle", 7 | "Only in the Android app" : "Slegs in die Android-toep", 8 | "Only in the iOS app" : "Slegs in die iOS-toep", 9 | "Only in the desktop client" : "Slegs in die werkskermkliënt", 10 | "Only in the browser" : "Slegs in die blaaier", 11 | "The given label is invalid" : "Die gegewe etiket is ongeldig", 12 | "The given URL is invalid" : "Die gegewe bronadres is ongeldig", 13 | "The given language does not exist" : "Die gegewe taal bestaan nie", 14 | "The given type is invalid" : "Die gegewe tipe is ongeldig", 15 | "The given device is invalid" : "Die gegewe toestel is ongeldig", 16 | "The given icon does not exist" : "Die gegewe ikoon bestaan nie", 17 | "The site does not exist" : "Die werf bestaan nie", 18 | "No file uploaded" : "Geen lêer opgelaai", 19 | "External sites" : "Eksterne werwe", 20 | "__language_name__" : "Afrikaans", 21 | "Name" : "Naam", 22 | "URL" : "Bronadres", 23 | "Language" : "Taal", 24 | "Groups" : "Groepe", 25 | "Devices" : "Toestelle", 26 | "Icon" : "Ikoon", 27 | "Position" : "Posisie", 28 | "Redirect" : "Herverwys", 29 | "Remove site" : "Verwyder werf", 30 | "New site" : "Nuwe werf" 31 | }, 32 | "nplurals=2; plural=(n != 1);"); 33 | -------------------------------------------------------------------------------- /l10n/be.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Выберыце значок", 5 | "All languages" : "Усе мовы", 6 | "User quota" : "Квота карыстальніка", 7 | "All devices" : "Усе прылады", 8 | "The given language does not exist" : "Гэта мова не існуе", 9 | "__language_name__" : "Беларуская", 10 | "Name" : "Назва", 11 | "URL" : "URL-адрас", 12 | "Language" : "Мова", 13 | "Groups" : "Групы", 14 | "Devices" : "Прылады", 15 | "Icon" : "Значок", 16 | "Delete icon" : "Выдаліць значок", 17 | "Uploading…" : "Запампоўванне…", 18 | "Reloading icon list…" : "Перазагрузка спісу значкоў…", 19 | "Icon could not be uploaded" : "Не ўдалося запампаваць значок", 20 | "A JSON Web Token containing user´s email, uid and display name in its payload can be embedded into the link using the {jwt} placeholder. See the {linkstart}documentation{linkend} how to decode it." : "JSON-токен, які змяшчае адрас электроннай пошты, UID і імя карыстальніка ў сваёй карыснай нагрузцы, можа быць убудаваны ў спасылку з дапамогай запаўняльніка {jwt}. Паглядзіце ў {linkstart}дакументацыі{linkend}, як яго расшыфраваць.", 21 | "Icons" : "Значкі", 22 | "Upload new icon" : "Запампаваць новы значок" 23 | }, 24 | "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); 25 | -------------------------------------------------------------------------------- /appinfo/routes.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | return [ 12 | 'routes' => [ 13 | ['name' => 'site#showDefaultPage', 'url' => '/', 'verb' => 'GET'], 14 | ['name' => 'icon#uploadIcon', 'url' => '/icons', 'verb' => 'POST'], 15 | ['name' => 'icon#showIcon', 'url' => '/icons/{icon}', 'verb' => 'GET'], 16 | ['name' => 'icon#deleteIcon', 'url' => '/icons/{icon}', 'verb' => 'DELETE'], 17 | ['name' => 'site#showPage', 'url' => '/{id}/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.*']], 18 | ], 19 | 'ocs' => [ 20 | ['name' => 'API#get', 'url' => '/api/{apiVersion}', 'verb' => 'GET', 'requirements' => ['apiVersion' => 'v1']], 21 | ['name' => 'API#getAdmin', 'url' => '/api/{apiVersion}/sites', 'verb' => 'GET', 'requirements' => ['apiVersion' => 'v1']], 22 | ['name' => 'API#add', 'url' => '/api/{apiVersion}/sites', 'verb' => 'POST', 'requirements' => ['apiVersion' => 'v1']], 23 | ['name' => 'API#update', 'url' => '/api/{apiVersion}/sites/{id}', 'verb' => 'PUT', 'requirements' => ['apiVersion' => 'v1', 'id' => '\d+']], 24 | ['name' => 'API#delete', 'url' => '/api/{apiVersion}/sites/{id}', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => 'v1', 'id' => '\d+']], 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: composer 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | day: saturday 8 | time: "03:00" 9 | timezone: Europe/Paris 10 | open-pull-requests-limit: 10 11 | - package-ecosystem: composer 12 | directory: "/vendor-bin/csfixer" 13 | schedule: 14 | interval: weekly 15 | day: saturday 16 | time: "03:00" 17 | timezone: Europe/Paris 18 | open-pull-requests-limit: 10 19 | - package-ecosystem: composer 20 | directory: "/vendor-bin/mozart" 21 | schedule: 22 | interval: weekly 23 | day: saturday 24 | time: "03:00" 25 | timezone: Europe/Paris 26 | open-pull-requests-limit: 10 27 | - package-ecosystem: composer 28 | directory: "/vendor-bin/phpunit" 29 | schedule: 30 | interval: weekly 31 | day: saturday 32 | time: "03:00" 33 | timezone: Europe/Paris 34 | open-pull-requests-limit: 10 35 | - package-ecosystem: composer 36 | directory: "/vendor-bin/psalm" 37 | schedule: 38 | interval: weekly 39 | day: saturday 40 | time: "03:00" 41 | timezone: Europe/Paris 42 | open-pull-requests-limit: 10 43 | - package-ecosystem: npm 44 | directory: "/" 45 | schedule: 46 | interval: weekly 47 | day: saturday 48 | time: "03:00" 49 | timezone: Europe/Paris 50 | open-pull-requests-limit: 10 51 | # Disable automatic rebasing because without a build CI will likely fail anyway 52 | rebase-strategy: "disabled" 53 | ignore: 54 | - dependency-name: css-loader 55 | versions: 56 | - ">= 4.a" 57 | - "< 5" 58 | -------------------------------------------------------------------------------- /.github/workflows/phpunit-summary-when-unrelated.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | name: PHPUnit summary 7 | 8 | on: 9 | pull_request: 10 | paths-ignore: 11 | - '.github/workflows/**' 12 | - 'appinfo/**' 13 | - 'lib/**' 14 | - 'templates/**' 15 | - 'tests/**' 16 | - 'vendor/**' 17 | - 'vendor-bin/**' 18 | - '.php-cs-fixer.dist.php' 19 | - 'composer.json' 20 | - 'composer.lock' 21 | 22 | permissions: 23 | contents: read 24 | 25 | jobs: 26 | summary-mysql: 27 | permissions: 28 | contents: none 29 | runs-on: ubuntu-latest 30 | 31 | name: phpunit-mysql-summary 32 | 33 | steps: 34 | - name: Summary status 35 | run: 'echo "No PHP files changed, skipped PHPUnit"' 36 | 37 | summary-oci: 38 | permissions: 39 | contents: none 40 | runs-on: ubuntu-latest 41 | 42 | name: phpunit-oci-summary 43 | 44 | steps: 45 | - name: Summary status 46 | run: 'echo "No PHP files changed, skipped PHPUnit"' 47 | 48 | summary-pgsql: 49 | permissions: 50 | contents: none 51 | runs-on: ubuntu-latest 52 | 53 | name: phpunit-pgsql-summary 54 | 55 | steps: 56 | - name: Summary status 57 | run: 'echo "No PHP files changed, skipped PHPUnit"' 58 | 59 | summary-sqlite: 60 | permissions: 61 | contents: none 62 | runs-on: ubuntu-latest 63 | 64 | name: phpunit-sqlite-summary 65 | 66 | steps: 67 | - name: Summary status 68 | run: 'echo "No PHP files changed, skipped PHPUnit"' 69 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-approve-merge.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Dependabot 10 | 11 | on: 12 | pull_request_target: # zizmor: ignore[dangerous-triggers] 13 | branches: 14 | - main 15 | - master 16 | - stable* 17 | 18 | permissions: 19 | contents: read 20 | 21 | concurrency: 22 | group: dependabot-approve-merge-${{ github.head_ref || github.run_id }} 23 | cancel-in-progress: true 24 | 25 | jobs: 26 | auto-approve-merge: 27 | if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'renovate[bot]' 28 | runs-on: ubuntu-latest-low 29 | permissions: 30 | # for hmarr/auto-approve-action to approve PRs 31 | pull-requests: write 32 | 33 | steps: 34 | - name: Disabled on forks 35 | if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} 36 | run: | 37 | echo 'Can not approve PRs from forks' 38 | exit 1 39 | 40 | # GitHub actions bot approve 41 | - uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2 42 | with: 43 | github-token: ${{ secrets.GITHUB_TOKEN }} 44 | 45 | # Nextcloud bot approve and merge request 46 | - uses: ahmadnassri/action-dependabot-auto-merge@45fc124d949b19b6b8bf6645b6c9d55f4f9ac61a # v2 47 | with: 48 | target: minor 49 | github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }} 50 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | ## Submitting issues 2 | 3 | If you have questions about how to install or use Nextcloud, please direct these to our [forum][forum]. We are also available on [IRC][irc]. 4 | 5 | ### Short version 6 | 7 | * The [**issue template can be found here**][template]. Please always use the issue template when reporting issues. 8 | 9 | ### Guidelines 10 | * Please search the existing issues first, it's likely that your issue was already reported or even fixed. 11 | - Go to one of the repositories, click "issues" and type any word in the top search/command bar. 12 | - You can also filter by appending e. g. "state:open" to the search string. 13 | - More info on [search syntax within github](https://help.github.com/articles/searching-issues) 14 | * This repository ([External sites](https://github.com/nextcloud/external/issues)) is *only* for issues within the External sites code. 15 | * __SECURITY__: Report any potential security bug to us via [our HackerOne page](https://hackerone.com/nextcloud) or security@nextcloud.com following our [security policy](https://nextcloud.com/security/) instead of filing an issue in our bug tracker 16 | * Report the issue using our [template][template], it includes all the information we need to track down the issue. 17 | 18 | Help us to maximize the effort we can spend fixing issues and adding new features, by not reporting duplicate issues. 19 | 20 | [template]: https://raw.github.com/nextcloud/external/master/.github/issue_template.md 21 | [forum]: https://help.nextcloud.com/ 22 | [irc]: https://webchat.freenode.net/?channels=nextcloud 23 | 24 | ### Contribute Code and translations 25 | Please check [server's contribution guidelines](https://github.com/nextcloud/server/blob/master/CONTRIBUTING.md#contributing-to-source-code) for further information about contributing code and translations. 26 | -------------------------------------------------------------------------------- /docs/jwt-sample.php: -------------------------------------------------------------------------------- 1 | 7 | * @license GNU AGPL version 3 or any later version 8 | * 9 | * SPDX-FileCopyrightText: 2022 Joas Schilling 10 | * SPDX-License-Identifier: AGPL-3.0-or-later 11 | */ 12 | 13 | include_once __DIR__ . '/vendor/autoload.php'; 14 | 15 | /** 16 | * Sample script for reading and verifying the JWT parameter of external sites 17 | * 18 | * 1. Install JWT 19 | * 20 | * composer require firebase/php-jwt 21 | * 22 | * 2. Define this page as external site with the parameter `?jwt={jwt}` 23 | * 3. Replace the key below with the result of the following command: 24 | * 25 | * occ config:app:get external jwt_token_pubkey_es256 26 | * 27 | * 4. The $decoded variable contains the JWT token details 28 | * 29 | * object(stdClass)[4] 30 | * public 'iss' => string 'https://nextcloud25.local/' (length=26) 31 | * public 'iat' => int 1663331793 32 | * public 'exp' => int 1663335393 33 | * public 'userdata' => 34 | * object(stdClass)[5] 35 | * public 'email' => string 'admin@schilljs.com' (length=18) 36 | * public 'uid' => string 'admin' (length=5) 37 | * public 'displayName' => string 'Laura Adams' (length=11) 38 | * 39 | */ 40 | 41 | $key = '-----BEGIN PUBLIC KEY----- 42 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEys95/Y0nsJZ/OIz59H1eOTHmzkBs 43 | d2yHITf+BPqxirqskhFpnF7OrXPG/i3HB2mC1JoBjvpGdWov0pkzst5CuQ== 44 | -----END PUBLIC KEY----- 45 | '; 46 | 47 | $jwt = rawurldecode($_REQUEST['jwt']); 48 | 49 | try { 50 | $keyO = new \Firebase\JWT\Key($key, 'ES256'); 51 | $decoded = \Firebase\JWT\JWT::decode($jwt, $keyO); 52 | var_dump($decoded); 53 | } catch (\Throwable $e) { 54 | var_dump($e); 55 | exit; 56 | } 57 | -------------------------------------------------------------------------------- /.github/workflows/lint-php-cs.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php-cs 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-php-cs-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | lint: 22 | runs-on: ubuntu-latest 23 | 24 | name: php-cs 25 | 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 29 | with: 30 | persist-credentials: false 31 | 32 | - name: Get php version 33 | id: versions 34 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 35 | 36 | - name: Set up php${{ steps.versions.outputs.php-min }} 37 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 38 | with: 39 | php-version: ${{ steps.versions.outputs.php-min }} 40 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 41 | coverage: none 42 | ini-file: development 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | 46 | - name: Install dependencies 47 | run: | 48 | composer remove nextcloud/ocp --dev --no-scripts 49 | composer i 50 | 51 | - name: Lint 52 | run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 ) 53 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoload": { 3 | "psr-4": { 4 | "OCA\\External\\": "lib/" 5 | } 6 | }, 7 | "autoload-dev": { 8 | "psr-4": { 9 | "OCP\\": "vendor/nextcloud/ocp/OCP" 10 | } 11 | }, 12 | "require-dev": { 13 | "nextcloud/ocp": "dev-master", 14 | "roave/security-advisories": "dev-latest" 15 | }, 16 | "scripts": { 17 | "lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l", 18 | "cs:check": "php-cs-fixer fix --dry-run --diff", 19 | "cs:fix": "php-cs-fixer fix", 20 | "psalm": "psalm --threads=1", 21 | "psalm:update-baseline": "psalm --threads=1 --update-baseline", 22 | "psalm:clear": "psalm --clear-cache && psalm --clear-global-cache", 23 | "psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType", 24 | "test:unit": "vendor/bin/phpunit -c tests/phpunit.xml", 25 | "post-install-cmd": [ 26 | "@composer bin all install --ansi", 27 | "\"vendor/bin/mozart\" compose", 28 | "composer dump-autoload" 29 | ], 30 | "post-update-cmd": [ 31 | "@composer bin all update --ansi", 32 | "\"vendor/bin/mozart\" compose", 33 | "composer dump-autoload" 34 | ] 35 | }, 36 | "config": { 37 | "allow-plugins": { 38 | "bamarni/composer-bin-plugin": true, 39 | "composer/package-versions-deprecated": true 40 | }, 41 | "autoloader-suffix": "External", 42 | "classmap-authoritative": true, 43 | "optimize-autoloader": true, 44 | "platform": { 45 | "php": "8.1" 46 | }, 47 | "sort-packages": true 48 | }, 49 | "extra": { 50 | "mozart": { 51 | "dep_namespace": "OCA\\External\\Vendor\\", 52 | "dep_directory": "/lib/Vendor/", 53 | "classmap_directory": "/lib/autoload/", 54 | "classmap_prefix": "NEXTCLOUDEXTERNALSITES_", 55 | "packages": [ 56 | "firebase/php-jwt" 57 | ] 58 | } 59 | }, 60 | "require": { 61 | "bamarni/composer-bin-plugin": "^1.8", 62 | "firebase/php-jwt": "^6.3" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /img/external.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /img/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /img/external-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /img/settings-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 8 | ### Steps to reproduce 9 | 1. 10 | 2. 11 | 3. 12 | 13 | ### Expected behaviour 14 | Tell us what should happen 15 | 16 | ### Actual behaviour 17 | Tell us what happens instead 18 | 19 | ### Server configuration 20 | 23 | 24 | **Operating system**: 25 | 26 | **Web server:** 27 | 28 | **Database:** 29 | 30 | **PHP version:** 31 | 32 | **Nextcloud version:** (see Nextcloud admin page) 33 | 34 | **Where did you install Nextcloud from:** 35 | 36 | 37 | **List of activated apps:** 38 | 39 | ``` 40 | If you have access to your command line run e.g.: 41 | sudo -u www-data php occ app:list 42 | from within your Nextcloud installation folder 43 | ``` 44 | 45 | **Nextcloud configuration:** 46 | 47 | ``` 48 | If you have access to your command line run e.g.: 49 | sudo -u www-data php occ config:list system 50 | from within your Nextcloud installation folder 51 | 52 | or 53 | 54 | Insert your config.php content here 55 | Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …) 56 | ``` 57 | 58 | ### Client configuration 59 | **Browser:** 60 | 61 | **Operating system:** 62 | 63 | ### Logs 64 | 65 | #### Nextcloud log (data/owncloud.log) 66 | ``` 67 | Insert your Nextcloud log here 68 | ``` 69 | 70 | #### Browser log 71 | ``` 72 | Insert your browser log here, this could for example include: 73 | 74 | a) The javascript console log 75 | b) The network log 76 | c) ... 77 | ``` 78 | -------------------------------------------------------------------------------- /lib/Settings/Personal.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2018 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Settings; 12 | 13 | use OCA\External\SitesManager; 14 | use OCP\AppFramework\Http\TemplateResponse; 15 | use OCP\IURLGenerator; 16 | use OCP\Settings\ISettings; 17 | 18 | class Personal implements ISettings { 19 | /** @var SitesManager */ 20 | protected $sitesManager; 21 | 22 | /** @var IURLGenerator */ 23 | protected $url; 24 | 25 | public function __construct(SitesManager $sitesManager, IURLGenerator $url) { 26 | $this->sitesManager = $sitesManager; 27 | $this->url = $url; 28 | } 29 | 30 | /** 31 | * @return TemplateResponse 32 | */ 33 | public function getForm() { 34 | $sites = $this->sitesManager->getSitesToDisplay(); 35 | 36 | $quotaLink = []; 37 | foreach ($sites as $site) { 38 | if ($site['type'] === SitesManager::TYPE_QUOTA) { 39 | $quotaLink = $site; 40 | break; 41 | } 42 | } 43 | 44 | $url = $quotaLink['url']; 45 | if (!$quotaLink['redirect']) { 46 | $url = $this->url->linkToRoute('external.site.showPage', ['id' => $quotaLink['id'], 'path' => '']); 47 | } 48 | 49 | return new TemplateResponse('external', 'quota', [ 50 | 'quotaLink' => $url, 51 | 'quotaName' => $quotaLink['name'], 52 | ], ''); 53 | } 54 | 55 | /** 56 | * @return string the section ID, e.g. 'sharing' 57 | */ 58 | public function getSection() { 59 | return 'personal-info'; 60 | } 61 | 62 | /** 63 | * @return int whether the form should be rather on the top or bottom of 64 | * the admin section. The forms are arranged in ascending order of the 65 | * priority values. It is required to return a value between 0 and 100. 66 | * 67 | * E.g.: 70 68 | */ 69 | public function getPriority() { 70 | return 55; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2017 Joas Schilling 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | .site-name, .site-url { 6 | width: 35%; 7 | } 8 | 9 | .site-lang, .site-icon, .site-device, .site-type { 10 | width: 20%; 11 | } 12 | 13 | .site-redirect-box { 14 | padding: 8px 0; 15 | } 16 | 17 | #external .icon-more { 18 | width: 16px; 19 | height: 16px; 20 | padding: 14px; 21 | opacity: .5; 22 | cursor: pointer; 23 | } 24 | 25 | #external .icon-more:hover { 26 | opacity: 1; 27 | } 28 | 29 | #external label > span { 30 | display: inline-block; 31 | min-width: 120px; 32 | } 33 | 34 | #external ul.external_sites > li { 35 | margin-left: -5px; 36 | padding: 5px 0 10px 5px; 37 | } 38 | 39 | #external ul.external_sites > li.saving { 40 | box-shadow: inset 2px 0 #CCCCCC; 41 | } 42 | 43 | #external ul.external_sites > li.saved { 44 | box-shadow: inset 2px 0 #00AA00; 45 | } 46 | 47 | #external ul.external_sites > li.failure { 48 | box-shadow: inset 2px 0 #AA0000; 49 | } 50 | 51 | #external ul.external_sites > li .options { 52 | padding: 0 10px; 53 | } 54 | 55 | #external ul.icon-list li { 56 | padding: 5px 0; 57 | display: inline-block; 58 | width: 33%; 59 | } 60 | 61 | #external ul.icon-list .img { 62 | padding: 5px; 63 | border-radius: 5px; 64 | background: #efefef; 65 | display: inline-block; 66 | } 67 | 68 | #external ul.icon-list .img img { 69 | width: 32px; 70 | vertical-align: middle; 71 | } 72 | 73 | #external ul.icon-list li.twin-icons img:first-child { 74 | margin-right: 5px; 75 | } 76 | 77 | #external ul.icon-list span { 78 | padding-left: 10px; 79 | } 80 | 81 | #external ul.icon-list span.icon-delete { 82 | padding-left: 25px; 83 | cursor: pointer; 84 | } 85 | 86 | #loading_sites { 87 | width: 512px; 88 | } 89 | 90 | .delete-button { 91 | margin-left: 123px; 92 | display: inline-block; 93 | } 94 | 95 | .invalid-value { 96 | border-color: #AA0000 !important; 97 | } 98 | 99 | #ifm { 100 | display: block; 101 | width: 100%; 102 | height: 100%; 103 | } 104 | -------------------------------------------------------------------------------- /l10n/mn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Сонгох тэмдэг ", 3 | "All languages" : "Бүх хэлүүд", 4 | "Header" : "Толгойн мэдээ", 5 | "Setting menu" : " цэсний тохиргоо", 6 | "User quota" : "хэрэглэгчийн ноогдол", 7 | "All devices" : "Бүх төхөөрөмж", 8 | "Only in the Android app" : "Зөвхөн андройд програм", 9 | "Only in the iOS app" : "Зөвхөн програм ", 10 | "Only in the desktop client" : "Зөвхөн харилцагчын дэлгэц ", 11 | "Only in the browser" : "Зөвхөн үзэх програм ", 12 | "The given label is invalid" : "Өгөгдсөн хаяг буруу байна", 13 | "The given URL is invalid" : " өгөдсөн нөөц заагч буруу байна", 14 | "The given language does not exist" : "Өгөгдсөн найруулага байхгүй байна", 15 | "The given type is invalid" : "Өгөгдсөн төрөл буруу байна", 16 | "The given device is invalid" : "Өгөгдсөн хэрэгсэл буруу байна", 17 | "The given icon does not exist" : "Өгөгдсөн тэмдэг байхгүй байна", 18 | "The site does not exist" : "Энэ сайт байхгүй байна", 19 | "No file uploaded" : "Файл илгээгдсэнгүй", 20 | "__language_name__" : "хэлний нэр", 21 | "Name" : "Нэр", 22 | "URL" : "URL", 23 | "Language" : "Хэл", 24 | "Groups" : "бүлэгүүд", 25 | "Devices" : "Төхөөрөмжүүд", 26 | "Icon" : "Тэмдэгт ", 27 | "Position" : "Байр", 28 | "Remove site" : "Цахим хуудсыг устгах", 29 | "New site" : "Шинэ сайт", 30 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Дээд талын цэсэнд байгаа програмын жагсаалтанд веб сайтаа нэмээрэй. Ингэснээр энэ нь бүх хэрэглэгчдэд харагдах ба бусад ашиглагдсан хуудас эсвэл чухал веб сайтруу ороход илүү хурдан амар болно", 31 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Үүнээс гадна ойрын үед маш олон сайтууд хуулбарлалт хийхийг аюулгүй байдлын шалтгааны улмаас хориглодог болсон", 32 | "We highly recommend to test the configured sites above properly." : "Бид тань дээр тохируулагдсан веб сайтуудыг тестлэж үзэхийг санал болгож байна", 33 | "Icons" : "тэмдэгт" 34 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 35 | } -------------------------------------------------------------------------------- /l10n/mn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Сонгох тэмдэг ", 5 | "All languages" : "Бүх хэлүүд", 6 | "Header" : "Толгойн мэдээ", 7 | "Setting menu" : " цэсний тохиргоо", 8 | "User quota" : "хэрэглэгчийн ноогдол", 9 | "All devices" : "Бүх төхөөрөмж", 10 | "Only in the Android app" : "Зөвхөн андройд програм", 11 | "Only in the iOS app" : "Зөвхөн програм ", 12 | "Only in the desktop client" : "Зөвхөн харилцагчын дэлгэц ", 13 | "Only in the browser" : "Зөвхөн үзэх програм ", 14 | "The given label is invalid" : "Өгөгдсөн хаяг буруу байна", 15 | "The given URL is invalid" : " өгөдсөн нөөц заагч буруу байна", 16 | "The given language does not exist" : "Өгөгдсөн найруулага байхгүй байна", 17 | "The given type is invalid" : "Өгөгдсөн төрөл буруу байна", 18 | "The given device is invalid" : "Өгөгдсөн хэрэгсэл буруу байна", 19 | "The given icon does not exist" : "Өгөгдсөн тэмдэг байхгүй байна", 20 | "The site does not exist" : "Энэ сайт байхгүй байна", 21 | "No file uploaded" : "Файл илгээгдсэнгүй", 22 | "__language_name__" : "хэлний нэр", 23 | "Name" : "Нэр", 24 | "URL" : "URL", 25 | "Language" : "Хэл", 26 | "Groups" : "бүлэгүүд", 27 | "Devices" : "Төхөөрөмжүүд", 28 | "Icon" : "Тэмдэгт ", 29 | "Position" : "Байр", 30 | "Remove site" : "Цахим хуудсыг устгах", 31 | "New site" : "Шинэ сайт", 32 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Дээд талын цэсэнд байгаа програмын жагсаалтанд веб сайтаа нэмээрэй. Ингэснээр энэ нь бүх хэрэглэгчдэд харагдах ба бусад ашиглагдсан хуудас эсвэл чухал веб сайтруу ороход илүү хурдан амар болно", 33 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Үүнээс гадна ойрын үед маш олон сайтууд хуулбарлалт хийхийг аюулгүй байдлын шалтгааны улмаас хориглодог болсон", 34 | "We highly recommend to test the configured sites above properly." : "Бид тань дээр тохируулагдсан веб сайтуудыг тестлэж үзэхийг санал болгож байна", 35 | "Icons" : "тэмдэгт" 36 | }, 37 | "nplurals=2; plural=(n != 1);"); 38 | -------------------------------------------------------------------------------- /lib/Migration/CopyDefaultIcons.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Migration; 12 | 13 | use OCP\App\IAppManager; 14 | use OCP\Files\IAppData; 15 | use OCP\Files\NotFoundException; 16 | use OCP\Files\SimpleFS\ISimpleFolder; 17 | use OCP\IL10N; 18 | use OCP\Migration\IOutput; 19 | use OCP\Migration\IRepairStep; 20 | 21 | class CopyDefaultIcons implements IRepairStep { 22 | protected IL10N $l; 23 | protected IAppManager $appManager; 24 | protected IAppData $appData; 25 | 26 | public function __construct(IL10N $l, IAppManager $appManager, IAppData $appData) { 27 | $this->l = $l; 28 | $this->appManager = $appManager; 29 | $this->appData = $appData; 30 | } 31 | 32 | public function getName(): string { 33 | return 'Copy default images to the app data directory'; 34 | } 35 | 36 | /** 37 | * @throws \Exception in case of failure 38 | */ 39 | public function run(IOutput $output): void { 40 | try { 41 | $folder = $this->appData->getFolder('icons'); 42 | } catch (NotFoundException $e) { 43 | $folder = $this->appData->newFolder('icons'); 44 | } 45 | 46 | $this->copyDefaultIcon($output, $folder, 'external.svg'); 47 | $this->copyDefaultIcon($output, $folder, 'external-dark.svg'); 48 | $this->copyDefaultIcon($output, $folder, 'settings.svg'); 49 | $this->copyDefaultIcon($output, $folder, 'settings-dark.svg'); 50 | } 51 | 52 | protected function copyDefaultIcon(IOutput $output, ISimpleFolder $folder, string $file): void { 53 | try { 54 | $folder->getFile($file); 55 | $output->info(sprintf('Icon %s already exists', $file)); 56 | return; 57 | } catch (NotFoundException $exception) { 58 | } 59 | 60 | // Default icon is missing, copy it from img/ 61 | $content = file_get_contents($this->appManager->getAppPath('external') . '/img/' . $file); 62 | if ($content === false) { 63 | $output->info(sprintf('Could not read icon %s', $file)); 64 | return; 65 | } 66 | 67 | $externalSVG = $folder->newFile($file); 68 | $externalSVG->putContent($content); 69 | 70 | $output->info(sprintf('Icon %s copied successfully', $file)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /appinfo/info.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | external 9 | External sites 10 | Add external sites to your Nextcloud navigation 11 | 16 | 17 | 8.0.0-dev.0 18 | agpl 19 | 20 | Joas Schilling 21 | 22 | External 23 | 24 | 25 | 26 | 27 | 28 | 29 | https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/external_sites.html 30 | 31 | 32 | customization 33 | integration 34 | tools 35 | 36 | https://github.com/nextcloud/external 37 | https://github.com/nextcloud/external/issues 38 | https://github.com/nextcloud/external.git 39 | 40 | https://github.com/nextcloud/external/raw/master/docs/admin-settings.png 41 | https://github.com/nextcloud/external/raw/master/docs/menu-and-settings-integration.png 42 | https://github.com/nextcloud/external/raw/master/docs/page-sample.png 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | OCA\External\Migration\CopyDefaultIcons 51 | OCA\External\Migration\JWTTokenPrivateKeySensitive 52 | 53 | 54 | OCA\External\Migration\CopyDefaultIcons 55 | 56 | 57 | 58 | 59 | OCA\External\Settings\Admin 60 | OCA\External\Settings\Section 61 | 62 | 63 | -------------------------------------------------------------------------------- /l10n/sq.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Përzgjidhni një ikonë", 3 | "All languages" : "Të gjitha gjuhët", 4 | "Header" : "Header", 5 | "Setting menu" : "Menuja e mjedisit", 6 | "User quota" : "Kuota e përdoruesit", 7 | "All devices" : "Të gjitha paisjet", 8 | "Only in the Android app" : "Vetëm në Android app", 9 | "Only in the iOS app" : "Vetëm në iOS app", 10 | "Only in the desktop client" : "Vetëm në desktopin e klientit", 11 | "Only in the browser" : "Vetëm në shfletues", 12 | "The given label is invalid" : "Kartela e dhënë është invalide ", 13 | "The given URL is invalid" : "URL-ja e dhënë është invalide ", 14 | "The given language does not exist" : "Gjuha e dhënë nuk ekziston ", 15 | "The given type is invalid" : "Tipi i dhënë është i pavlefshëm", 16 | "The given device is invalid" : "Pajisja e dhënë është invalide ", 17 | "The given icon does not exist" : "Ikona e dhënë nuk ekziston ", 18 | "The site does not exist" : "Kjo faqe nuk ekziston ", 19 | "No file uploaded" : "Asnjë skedar i ngarkuar", 20 | "External sites" : "Faqe të jashtme", 21 | "__language_name__" : "Shqip", 22 | "Name" : "Emër", 23 | "URL" : "URL", 24 | "Language" : "Gjuha", 25 | "Groups" : "Grupet", 26 | "Devices" : "Pajisjet", 27 | "Icon" : "Ikonë", 28 | "Position" : "Pozicion", 29 | "Redirect" : "Ridrejto", 30 | "Remove site" : "Hiqe vendndodhjen", 31 | "New site" : "Faqe e re", 32 | "Uploading…" : "Po ngarkohet…", 33 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Shto një faqe interneti direkt në listën e aplikacioneve në shiritin e sipërm. Kjo do të jetë e dukshme për të gjithë përdoruesit dhe është e dobishme për të shpejt të arritur aplikacione të tjera të përdorura brenda vendit ose faqe të rëndësishme.", 34 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Për më tepër, ju lutemi, kini parasysh që mjaft sajte në këto kohë s’lejojnë iframing, për arsye sigurie.", 35 | "We highly recommend to test the configured sites above properly." : "Ne rekomandojmë të testoni faqeve e konfiguruara më lart siç duhet.", 36 | "Icons" : "Ikona", 37 | "Upload new icon" : "Ngarko ikonë të re" 38 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 39 | } -------------------------------------------------------------------------------- /.github/workflows/psalm.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Static analysis 10 | 11 | on: pull_request 12 | 13 | concurrency: 14 | group: psalm-${{ github.head_ref || github.run_id }} 15 | cancel-in-progress: true 16 | 17 | permissions: 18 | contents: read 19 | 20 | jobs: 21 | static-analysis: 22 | runs-on: ubuntu-latest 23 | 24 | name: static-psalm-analysis 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Get php version 32 | id: versions 33 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 34 | 35 | - name: Check enforcement of minimum PHP version ${{ steps.versions.outputs.php-min }} in psalm.xml 36 | run: grep 'phpVersion="${{ steps.versions.outputs.php-min }}' psalm.xml 37 | 38 | - name: Set up php${{ steps.versions.outputs.php-available }} 39 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 40 | with: 41 | php-version: ${{ steps.versions.outputs.php-available }} 42 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 43 | coverage: none 44 | ini-file: development 45 | # Temporary workaround for missing pcntl_* in PHP 8.3 46 | ini-values: disable_functions= 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 49 | 50 | - name: Install dependencies 51 | run: | 52 | composer remove nextcloud/ocp --dev --no-scripts 53 | composer i 54 | 55 | - name: Install nextcloud/ocp 56 | run: composer require --dev nextcloud/ocp:dev-${{ steps.versions.outputs.branches-max }} --ignore-platform-reqs --with-dependencies 57 | 58 | - name: Run coding standards check 59 | run: composer run psalm -- --threads=1 --monochrome --no-progress --output-format=github 60 | -------------------------------------------------------------------------------- /l10n/sq.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Përzgjidhni një ikonë", 5 | "All languages" : "Të gjitha gjuhët", 6 | "Header" : "Header", 7 | "Setting menu" : "Menuja e mjedisit", 8 | "User quota" : "Kuota e përdoruesit", 9 | "All devices" : "Të gjitha paisjet", 10 | "Only in the Android app" : "Vetëm në Android app", 11 | "Only in the iOS app" : "Vetëm në iOS app", 12 | "Only in the desktop client" : "Vetëm në desktopin e klientit", 13 | "Only in the browser" : "Vetëm në shfletues", 14 | "The given label is invalid" : "Kartela e dhënë është invalide ", 15 | "The given URL is invalid" : "URL-ja e dhënë është invalide ", 16 | "The given language does not exist" : "Gjuha e dhënë nuk ekziston ", 17 | "The given type is invalid" : "Tipi i dhënë është i pavlefshëm", 18 | "The given device is invalid" : "Pajisja e dhënë është invalide ", 19 | "The given icon does not exist" : "Ikona e dhënë nuk ekziston ", 20 | "The site does not exist" : "Kjo faqe nuk ekziston ", 21 | "No file uploaded" : "Asnjë skedar i ngarkuar", 22 | "External sites" : "Faqe të jashtme", 23 | "__language_name__" : "Shqip", 24 | "Name" : "Emër", 25 | "URL" : "URL", 26 | "Language" : "Gjuha", 27 | "Groups" : "Grupet", 28 | "Devices" : "Pajisjet", 29 | "Icon" : "Ikonë", 30 | "Position" : "Pozicion", 31 | "Redirect" : "Ridrejto", 32 | "Remove site" : "Hiqe vendndodhjen", 33 | "New site" : "Faqe e re", 34 | "Uploading…" : "Po ngarkohet…", 35 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Shto një faqe interneti direkt në listën e aplikacioneve në shiritin e sipërm. Kjo do të jetë e dukshme për të gjithë përdoruesit dhe është e dobishme për të shpejt të arritur aplikacione të tjera të përdorura brenda vendit ose faqe të rëndësishme.", 36 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Për më tepër, ju lutemi, kini parasysh që mjaft sajte në këto kohë s’lejojnë iframing, për arsye sigurie.", 37 | "We highly recommend to test the configured sites above properly." : "Ne rekomandojmë të testoni faqeve e konfiguruara më lart siç duhet.", 38 | "Icons" : "Ikona", 39 | "Upload new icon" : "Ngarko ikonë të re" 40 | }, 41 | "nplurals=2; plural=(n != 1);"); 42 | -------------------------------------------------------------------------------- /.github/workflows/lint-php.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint php 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-php-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | matrix: 22 | runs-on: ubuntu-latest-low 23 | outputs: 24 | php-versions: ${{ steps.versions.outputs.php-versions }} 25 | steps: 26 | - name: Checkout app 27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Get version matrix 32 | id: versions 33 | uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.0.0 34 | 35 | php-lint: 36 | runs-on: ubuntu-latest 37 | needs: matrix 38 | strategy: 39 | matrix: 40 | php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}} 41 | 42 | name: php-lint 43 | 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 47 | with: 48 | persist-credentials: false 49 | 50 | - name: Set up php ${{ matrix.php-versions }} 51 | uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0 52 | with: 53 | php-version: ${{ matrix.php-versions }} 54 | extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite 55 | coverage: none 56 | ini-file: development 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | 60 | - name: Lint 61 | run: composer run lint 62 | 63 | summary: 64 | permissions: 65 | contents: none 66 | runs-on: ubuntu-latest-low 67 | needs: php-lint 68 | 69 | if: always() 70 | 71 | name: php-lint-summary 72 | 73 | steps: 74 | - name: Summary status 75 | run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi 76 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2017-2022 Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | app_name=external 4 | 5 | project_dir=$(CURDIR)/../$(app_name) 6 | build_dir=$(CURDIR)/build/artifacts 7 | appstore_dir=$(build_dir)/appstore 8 | source_dir=$(build_dir)/source 9 | sign_dir=$(build_dir)/sign 10 | package_name=$(app_name) 11 | cert_dir=$(HOME)/.nextcloud/certificates 12 | version+=master 13 | 14 | all: appstore build-js-production 15 | 16 | dev-setup: clean-dev composer-install-dev npm-init 17 | 18 | release: appstore create-tag 19 | 20 | build-js: 21 | npm run dev 22 | 23 | build-js-production: 24 | npm run build 25 | 26 | watch-js: 27 | npm run watch 28 | 29 | composer-install-dev: 30 | composer install 31 | 32 | composer-install-production: 33 | composer install --no-dev 34 | 35 | test: 36 | npm run test:unit 37 | 38 | lint: 39 | npm run lint 40 | 41 | lint-fix: 42 | npm run lint:fix 43 | 44 | npm-init: 45 | npm ci 46 | 47 | npm-update: 48 | npm update 49 | 50 | clean: 51 | rm -rf js/dist/* 52 | rm -rf $(build_dir) 53 | 54 | clean-dev: clean 55 | rm -rf node_modules 56 | 57 | create-tag: 58 | git tag -s -a v$(version) -m "Tagging the $(version) release." 59 | git push origin v$(version) 60 | 61 | js-templates: 62 | handlebars -n OCA.External.Templates js/templates -f js/templates.js 63 | rm -rf node_modules 64 | 65 | appstore: clean composer-install-production npm-init build-js-production 66 | mkdir -p $(sign_dir) 67 | rsync -a \ 68 | --exclude=/.git \ 69 | --exclude=/.github \ 70 | --exclude=/.tx \ 71 | --exclude=/build \ 72 | --exclude=/docs \ 73 | --exclude=/l10n/l10n.pl \ 74 | --exclude=/node_modules \ 75 | --exclude=/screenshots \ 76 | --exclude=/src \ 77 | --exclude=/tests \ 78 | --exclude=/translationfiles \ 79 | --exclude=/vendor \ 80 | --exclude=/vendor-bin \ 81 | --exclude=.php-cs-fixer.cache \ 82 | --exclude=.php-cs-fixer.dist.php \ 83 | --exclude=/composer.json \ 84 | --exclude=/composer.lock \ 85 | --exclude=/README.md \ 86 | --exclude=/.gitattributes \ 87 | --exclude=/.gitignore \ 88 | --exclude=/.scrutinizer.yml \ 89 | --exclude=/.travis.yml \ 90 | --exclude=/.drone.yml \ 91 | --exclude=/babel.config.js \ 92 | --exclude=/.eslintrc.js \ 93 | --exclude=/Makefile \ 94 | --exclude=/package.json \ 95 | --exclude=/package-lock.json \ 96 | --exclude=/psalm.xml \ 97 | --exclude=/webpack.config.js \ 98 | $(project_dir)/ $(sign_dir)/$(app_name) 99 | tar -czf $(build_dir)/$(app_name).tar.gz \ 100 | -C $(sign_dir) $(app_name) 101 | @if [ -f $(cert_dir)/$(app_name).key ]; then \ 102 | echo "Signing package…"; \ 103 | openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(build_dir)/$(app_name).tar.gz | openssl base64; \ 104 | fi 105 | -------------------------------------------------------------------------------- /js/templates/site.handlebars: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | 5 | 6 | 85 |
  • 86 | -------------------------------------------------------------------------------- /.github/workflows/pr-feedback.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-FileCopyrightText: 2023 Marcel Klehr 8 | # SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com> 9 | # SPDX-FileCopyrightText: 2023 Daniel Kesselberg 10 | # SPDX-FileCopyrightText: 2023 Florian Steffens 11 | # SPDX-License-Identifier: MIT 12 | 13 | name: 'Ask for feedback on PRs' 14 | on: 15 | schedule: 16 | - cron: '30 1 * * *' 17 | 18 | permissions: 19 | contents: read 20 | pull-requests: write 21 | 22 | jobs: 23 | pr-feedback: 24 | if: ${{ github.repository_owner == 'nextcloud' }} 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: The get-github-handles-from-website action 28 | uses: marcelklehr/get-github-handles-from-website-action@06b2239db0a48fe1484ba0bfd966a3ab81a08308 # v1.0.1 29 | id: scrape 30 | with: 31 | website: 'https://nextcloud.com/team/' 32 | 33 | - name: Get blocklist 34 | id: blocklist 35 | run: | 36 | blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -) 37 | echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT" 38 | 39 | - uses: nextcloud/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4 # main 40 | with: 41 | feedback-message: | 42 | Hello there, 43 | Thank you so much for taking the time and effort to create a pull request to our Nextcloud project. 44 | 45 | We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. 46 | 47 | Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 48 | 49 | Thank you for contributing to Nextcloud and we hope to hear from you soon! 50 | 51 | (If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).) 52 | days-before-feedback: 14 53 | start-date: '2024-04-30' 54 | exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}' 55 | exempt-bots: true 56 | -------------------------------------------------------------------------------- /lib/AppInfo/Application.php: -------------------------------------------------------------------------------- 1 | 6 | * @license GNU AGPL version 3 or any later version 7 | * 8 | * SPDX-FileCopyrightText: 2020 Joas Schilling 9 | * SPDX-License-Identifier: AGPL-3.0-or-later 10 | */ 11 | 12 | namespace OCA\External\AppInfo; 13 | 14 | use OCA\External\BeforeTemplateRenderedListener; 15 | use OCA\External\Capabilities; 16 | use OCA\External\Settings\Personal; 17 | use OCA\External\SitesManager; 18 | use OCA\Files\Event\LoadAdditionalScriptsEvent; 19 | use OCP\AppFramework\App; 20 | use OCP\AppFramework\Bootstrap\IBootContext; 21 | use OCP\AppFramework\Bootstrap\IBootstrap; 22 | use OCP\AppFramework\Bootstrap\IRegistrationContext; 23 | use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; 24 | use OCP\INavigationManager; 25 | use OCP\IURLGenerator; 26 | use OCP\Settings\IManager; 27 | 28 | class Application extends App implements IBootstrap { 29 | public const APP_ID = 'external'; 30 | 31 | public function __construct() { 32 | parent::__construct(self::APP_ID); 33 | } 34 | 35 | public function register(IRegistrationContext $context): void { 36 | $context->registerCapability(Capabilities::class); 37 | $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); 38 | $context->registerEventListener(LoadAdditionalScriptsEvent::class, BeforeTemplateRenderedListener::class); 39 | } 40 | 41 | public function boot(IBootContext $context): void { 42 | $context->injectFn([$this, 'registerSites']); 43 | } 44 | 45 | public function registerSites( 46 | SitesManager $sitesManager, 47 | IManager $settingsManager, 48 | INavigationManager $navigationManager, 49 | IURLGenerator $url): void { 50 | $sites = $sitesManager->getSitesToDisplay(); 51 | 52 | foreach ($sites as $site) { 53 | if ($site['type'] === SitesManager::TYPE_QUOTA) { 54 | $settingsManager->registerSetting(IManager::SETTINGS_PERSONAL, Personal::class); 55 | continue; 56 | } 57 | 58 | if ($site['type'] !== SitesManager::TYPE_LINK 59 | && $site['type'] !== SitesManager::TYPE_SETTING 60 | && $site['type'] !== SitesManager::TYPE_LOGIN) { 61 | continue; 62 | } 63 | 64 | $navigationManager->add(function () use ($site, $url) { 65 | if ($site['icon'] !== '') { 66 | $image = $url->linkToRoute('external.icon.showIcon', ['icon' => $site['icon']]); 67 | } else { 68 | $image = $url->linkToRoute('external.icon.showIcon', ['icon' => 'external.svg']); 69 | } 70 | 71 | $href = $site['url']; 72 | if (!$site['redirect']) { 73 | $href = $url->linkToRoute('external.site.showPage', ['id' => $site['id'], 'path' => '']); 74 | } 75 | 76 | return [ 77 | 'id' => 'external_index' . $site['id'], 78 | 'order' => 80 + $site['id'], 79 | 'href' => $href, 80 | 'icon' => $image, 81 | 'type' => $site['type'], 82 | 'name' => $site['name'], 83 | 'target' => $site['redirect'], 84 | ]; 85 | }); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # External sites 2 | 3 | [![REUSE status](https://api.reuse.software/badge/github.com/nextcloud/external)](https://api.reuse.software/info/github.com/nextcloud/external) 4 | 5 | This application allows an admin to add a link in the Nextcloud web interface 6 | Apps menu that points to an external website. By simply entering the URL and 7 | the name for the external site, an icon appears. When this icon is clicked by a 8 | user, the external website appears in the Nextcloud frame. For the user, this 9 | external site appears as if it is part of Nextcloud but, in fact, this can be 10 | any external URL. 11 | 12 | ## **🛠 State of maintenance** 13 | 14 | While there are many things that could be done to further improve this app, the app is currently maintained with **limited effort**. This means: 15 | 16 | - The main functionality works for the majority of the use cases 17 | - We will ensure that the app will continue to work like this for future releases and we will fix bugs that we classify as 'critical' 18 | - We will not invest further development resources ourselves in advancing the app with new features 19 | - We do review and enthusiastically welcome community PR's 20 | 21 | We would be more than excited if you would like to collaborate with us. We will merge pull requests for new features and fixes. We also would love to welcome co-maintainers. 22 | 23 | ## OCS API 24 | 25 | It is also possible to get the sites via an OCS endpoint. The request must be authenticated. 26 | Only sites for the user´s language are returned: 27 | ```bash 28 | curl -H "OCS-APIRequest: true" \ 29 | https://admin:admin@localhost/ocs/v2.php/apps/external/api/v1 30 | ``` 31 | 32 | ### Response 33 | ```xml 34 | 35 | 36 | 37 | ok 38 | 200 39 | OK 40 | 41 | 42 | 43 | 23 44 | Homepage 45 | https://localhost/index.php 46 | link 47 | 0 48 | https://localhost/external.svg 49 | 50 | 51 | 52 | ``` 53 | 54 | #### Explanation 55 | 56 | | Field | Type | Description | 57 | | ----- | ------ | ---------------------------------------- | 58 | | id | int | Numeric identifier of the site | 59 | | name | string | Name of the site, ready to use | 60 | | url | string | URL that should be framed/linked to | 61 | | redirect | int | Whether the link should be opened inline or in a new window | 62 | | type | string | Can be one of `link`, `settings` or `quota`; see [this issue](https://github.com/nextcloud/external/issues/7) for details | 63 | | icon | string | Full URL of the icon that should be shown next to the name of the link | 64 | 65 | ### ETag / If-None-Match 66 | 67 | The API provides an ETag for the sites array. In case the ETag matches the given value, a `304 Not Modified` is delivered together with an empty response body. 68 | 69 | ### Capability 70 | 71 | The app registers a capability, so clients can check that before making the actual OCS request: 72 | ```xml 73 | 74 | 75 | ... 76 | 77 | 78 | ... 79 | 80 | 81 | sites 82 | device 83 | groups 84 | redirect 85 | 86 | 87 | ... 88 | ``` 89 | -------------------------------------------------------------------------------- /l10n/ro.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selectați o pictogramă", 3 | "All languages" : "Toate limbile", 4 | "Header" : "Antet", 5 | "Setting menu" : "Meniul Setări", 6 | "User quota" : "Procentajul utilizatorului", 7 | "All devices" : "Toate dispozitivele", 8 | "Only in the Android app" : "Numai în aplicația Android", 9 | "Only in the iOS app" : "Numai în aplicația IOS", 10 | "Only in the desktop client" : "Numai în programul pentru desktop", 11 | "Only in the browser" : "Numai în browser", 12 | "The given label is invalid" : "Eticheta respectivă nu este validă", 13 | "The given URL is invalid" : "URL-ul respectiv nu este valid", 14 | "The given language does not exist" : "Limba respectivă nu există", 15 | "The given type is invalid" : "Modul respectiv nu este valid", 16 | "The given device is invalid" : "Dispozitivul respectiv nu este valid", 17 | "At least one of the given groups does not exist" : "Cel puțin unul din grupurile prezentate nu există", 18 | "The given icon does not exist" : "Pictograma respectivă nu există", 19 | "The site does not exist" : "Pagina nu există", 20 | "No file uploaded" : "Nu a fost încărcat niciun fișier", 21 | "Provided file is not an image" : "Fișierul selectat nu este o imagine.", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "Imaginea selectată nu este un pătrat cu dimensiunile de 16,24 sau 32 pixeli", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "A apărut o eroare in timp ce încărcam pictograma,te rog asigură-te că directorul data are permisiuni de scriere", 24 | "External sites" : "Pagini externe", 25 | "__language_name__" : "Română", 26 | "Add external sites to your Nextcloud navigation" : "Adaugă pagini externe la navigarea Nextcloud-ului tău", 27 | "Name" : "Nume", 28 | "URL" : "URL", 29 | "Language" : "Limba", 30 | "Groups" : "Grupuri", 31 | "Devices" : "Dispozitive", 32 | "Icon" : "Pictogramă", 33 | "Position" : "Poziție", 34 | "Redirect" : "Deviere", 35 | "Remove site" : "Înlătură pagina", 36 | "New site" : "Pagină nouă", 37 | "Delete icon" : "Șterge iconița", 38 | "Uploading…" : "Încărcare...", 39 | "Reloading icon list…" : "Reîncarc lista de pictograme...", 40 | "Icon could not be uploaded" : "Pictograma nu a putut fi încărcată", 41 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Adaugă un website direct în lista de aplicații din bara de sus. Acesta va fi vizibil pentru toți utilizatorii și este folositor pentru a ajunge rapid la alte aplicații web folosite sau pagini importante.", 42 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "În plus, vă rugăm să rețineți că în prezent multe site-uri Web interzic folosirea tehnicilor iframe din motive de securitate.", 43 | "We highly recommend to test the configured sites above properly." : "Recomandăm insistent testarea riguroasă a paginilor configurate mai sus.", 44 | "Icons" : "Pictograme", 45 | "Uploading an icon with the same name will replace the current icon." : "Încărcarea pictogramei cu aceelași nume va înlocui pictograma curentă.", 46 | "Upload new icon" : "Încarcă o nouă pictogramă" 47 | },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" 48 | } -------------------------------------------------------------------------------- /l10n/ro.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selectați o pictogramă", 5 | "All languages" : "Toate limbile", 6 | "Header" : "Antet", 7 | "Setting menu" : "Meniul Setări", 8 | "User quota" : "Procentajul utilizatorului", 9 | "All devices" : "Toate dispozitivele", 10 | "Only in the Android app" : "Numai în aplicația Android", 11 | "Only in the iOS app" : "Numai în aplicația IOS", 12 | "Only in the desktop client" : "Numai în programul pentru desktop", 13 | "Only in the browser" : "Numai în browser", 14 | "The given label is invalid" : "Eticheta respectivă nu este validă", 15 | "The given URL is invalid" : "URL-ul respectiv nu este valid", 16 | "The given language does not exist" : "Limba respectivă nu există", 17 | "The given type is invalid" : "Modul respectiv nu este valid", 18 | "The given device is invalid" : "Dispozitivul respectiv nu este valid", 19 | "At least one of the given groups does not exist" : "Cel puțin unul din grupurile prezentate nu există", 20 | "The given icon does not exist" : "Pictograma respectivă nu există", 21 | "The site does not exist" : "Pagina nu există", 22 | "No file uploaded" : "Nu a fost încărcat niciun fișier", 23 | "Provided file is not an image" : "Fișierul selectat nu este o imagine.", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "Imaginea selectată nu este un pătrat cu dimensiunile de 16,24 sau 32 pixeli", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "A apărut o eroare in timp ce încărcam pictograma,te rog asigură-te că directorul data are permisiuni de scriere", 26 | "External sites" : "Pagini externe", 27 | "__language_name__" : "Română", 28 | "Add external sites to your Nextcloud navigation" : "Adaugă pagini externe la navigarea Nextcloud-ului tău", 29 | "Name" : "Nume", 30 | "URL" : "URL", 31 | "Language" : "Limba", 32 | "Groups" : "Grupuri", 33 | "Devices" : "Dispozitive", 34 | "Icon" : "Pictogramă", 35 | "Position" : "Poziție", 36 | "Redirect" : "Deviere", 37 | "Remove site" : "Înlătură pagina", 38 | "New site" : "Pagină nouă", 39 | "Delete icon" : "Șterge iconița", 40 | "Uploading…" : "Încărcare...", 41 | "Reloading icon list…" : "Reîncarc lista de pictograme...", 42 | "Icon could not be uploaded" : "Pictograma nu a putut fi încărcată", 43 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Adaugă un website direct în lista de aplicații din bara de sus. Acesta va fi vizibil pentru toți utilizatorii și este folositor pentru a ajunge rapid la alte aplicații web folosite sau pagini importante.", 44 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "În plus, vă rugăm să rețineți că în prezent multe site-uri Web interzic folosirea tehnicilor iframe din motive de securitate.", 45 | "We highly recommend to test the configured sites above properly." : "Recomandăm insistent testarea riguroasă a paginilor configurate mai sus.", 46 | "Icons" : "Pictograme", 47 | "Uploading an icon with the same name will replace the current icon." : "Încărcarea pictogramei cu aceelași nume va înlocui pictograma curentă.", 48 | "Upload new icon" : "Încarcă o nouă pictogramă" 49 | }, 50 | "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); 51 | -------------------------------------------------------------------------------- /.github/workflows/node.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Node 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: node-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | changes: 22 | runs-on: ubuntu-latest-low 23 | permissions: 24 | contents: read 25 | pull-requests: read 26 | 27 | outputs: 28 | src: ${{ steps.changes.outputs.src}} 29 | 30 | steps: 31 | - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 32 | id: changes 33 | continue-on-error: true 34 | with: 35 | filters: | 36 | src: 37 | - '.github/workflows/**' 38 | - 'src/**' 39 | - 'appinfo/info.xml' 40 | - 'package.json' 41 | - 'package-lock.json' 42 | - 'tsconfig.json' 43 | - '**.js' 44 | - '**.ts' 45 | - '**.vue' 46 | 47 | build: 48 | runs-on: ubuntu-latest 49 | 50 | needs: changes 51 | if: needs.changes.outputs.src != 'false' 52 | 53 | name: NPM build 54 | steps: 55 | - name: Checkout 56 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 57 | with: 58 | persist-credentials: false 59 | 60 | - name: Read package.json node and npm engines version 61 | uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 62 | id: versions 63 | with: 64 | fallbackNode: '^20' 65 | fallbackNpm: '^10' 66 | 67 | - name: Set up node ${{ steps.versions.outputs.nodeVersion }} 68 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 69 | with: 70 | node-version: ${{ steps.versions.outputs.nodeVersion }} 71 | 72 | - name: Set up npm ${{ steps.versions.outputs.npmVersion }} 73 | run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' 74 | 75 | - name: Install dependencies & build 76 | env: 77 | CYPRESS_INSTALL_BINARY: 0 78 | PUPPETEER_SKIP_DOWNLOAD: true 79 | run: | 80 | npm ci 81 | npm run build --if-present 82 | 83 | - name: Check webpack build changes 84 | run: | 85 | bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please recompile and commit the assets, see the section \"Show changes on failure\" for details' && exit 1)" 86 | 87 | - name: Show changes on failure 88 | if: failure() 89 | run: | 90 | git status 91 | git --no-pager diff 92 | exit 1 # make it red to grab attention 93 | 94 | summary: 95 | permissions: 96 | contents: none 97 | runs-on: ubuntu-latest-low 98 | needs: [changes, build] 99 | 100 | if: always() 101 | 102 | # This is the summary, we just avoid to rename it so that branch protection rules still match 103 | name: node 104 | 105 | steps: 106 | - name: Summary status 107 | run: if ${{ needs.changes.outputs.src != 'false' && needs.build.result != 'success' }}; then exit 1; fi 108 | -------------------------------------------------------------------------------- /l10n/ko.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "아이콘 선택", 3 | "All languages" : "모든 언어", 4 | "Header" : "머리글", 5 | "Setting menu" : "설정 메뉴", 6 | "User quota" : "사용자 할당량", 7 | "Public footer" : "공개 바닥글", 8 | "All devices" : "모든 장치", 9 | "Only in the Android app" : "Android 앱만", 10 | "Only in the iOS app" : "iOS 앱만", 11 | "Only in the desktop client" : "데스크톱 클라이언트만", 12 | "Only in the browser" : "브라우저만", 13 | "The given label is invalid" : "지정한 레이블이 잘못됨", 14 | "The given URL is invalid" : "지정한 URL이 잘못됨", 15 | "The given language does not exist" : "지정한 언어가 존재하지 않음", 16 | "The given type is invalid" : "지정한 형식이 잘못됨", 17 | "The given device is invalid" : "지정한 장치가 잘못됨", 18 | "At least one of the given groups does not exist" : "최소한 하나의 지정한 그룹이 존재하지 않음", 19 | "The given icon does not exist" : "지정한 아이콘이 존재하지 않음", 20 | "The site does not exist" : "사이트가 존재하지 않음", 21 | "No file uploaded" : "업로드한 파일 없음", 22 | "Provided file is not an image" : "지정한 파일이 사진이 아님", 23 | "Provided image is not a square of 16, 24 or 32 pixels width" : "지정한 사진이 16, 24, 32픽셀 정사각형이 아님", 24 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "아이콘을 업로드하는 중 오류 발생, 데이터 디렉터리에 쓰기 권한이 있는지 확인하십시오", 25 | "External sites" : "외부 사이트", 26 | "__language_name__" : "한국어", 27 | "Add external sites to your Nextcloud navigation" : "Nextcloud 탐색에 외부 사이트 추가", 28 | "This application allows an admin to add additional links into the Nextcloud menus.\nFollowing a link, the external website appears in the Nextcloud frame.\nIt is also possible to add links only for a given language, device type or user group.\n\nMore information is available in the External sites documentation." : "이 앱을 사용하여 관리자가 Nextcloud 메뉴에 추가 링크를 추가할 수 있습니다.\n해당 링크를 누르면 외부 웹 사이트를 Nextcloud 프레임에 표시합니다.\n언어별, 장치 종류별, 사용자 그룹별로 링크를 추가할 수 있습니다.\n\n더 많은 정보를 보려면 외부 사이트 문서를 참조하십시오.", 29 | "Name" : "이름", 30 | "URL" : "URL", 31 | "Language" : "언어", 32 | "Groups" : "그룹", 33 | "Devices" : "장치", 34 | "Icon" : "아이콘", 35 | "Position" : "위치", 36 | "Redirect" : "넘겨주기", 37 | "Remove site" : "사이트 삭제", 38 | "This site does not allow embedding" : "이 사이트에서 임베딩을 허용하지 않음", 39 | "New site" : "새 사이트", 40 | "Delete icon" : "아이콘 삭제", 41 | "Uploading…" : "업로드 중…", 42 | "Reloading icon list…" : "아이콘 목록을 새로 고치는 중…", 43 | "Icon could not be uploaded" : "아이콘을 업로드할 수 없음", 44 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "웹 사이트를 상단 표시줄의 앱 목록에 바로 추가합니다. 모든 사용자가 볼 수 있으며 다른 내부 웹 앱이나 웹 사이트에 빠르게 접근할 수 있도록 합니다.", 45 | "Please note that some browsers will block displaying of sites via HTTP if you are running HTTPS." : "HTTPS를 사용하는 경우 일부 브라우저에서는 HTTP를 통한 사이트는 표시되지 않을 수 있습니다.", 46 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "또한 많은 웹 사이트에서 보안상의 이유로 iframe 사용을 금지하고 있습니다.", 47 | "We highly recommend to test the configured sites above properly." : "설정한 사이트가 올바르게 작동하는지 테스트하는 것을 추천합니다.", 48 | "Icons" : "아이콘", 49 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "test.png, test-dark.png 파일을 업로드하면 두 파일을 하나의 아이콘으로 사용합니다. 모바일 장치에서는 어두운 버전을 사용하며, 사용할 수 없는 경우에는 흰색 아이콘이 모바일 앱의 흰색 배경에서 보이지 않을 수도 있습니다.", 50 | "Uploading an icon with the same name will replace the current icon." : "같은 이름의 아이콘을 새로 업로드하면 현재 아이콘을 대체합니다.", 51 | "Upload new icon" : "새 아이콘 업로드" 52 | },"pluralForm" :"nplurals=1; plural=0;" 53 | } -------------------------------------------------------------------------------- /templates/settings.php: -------------------------------------------------------------------------------- 1 | 4 | * @copyright Copyright (c) 2012 Frank Karlitschek 5 | * @author Frank Karlitschek 6 | * @author Joas Schilling 7 | * @license GNU AGPL version 3 or any later version 8 | * 9 | * SPDX-FileCopyrightText: 2017 Joas Schilling 10 | * SPDX-FileCopyrightText: 2012 Frank Karlitschek 11 | * SPDX-License-Identifier: AGPL-3.0-or-later 12 | */ 13 | 14 | style('external', 'style'); 15 | script('external', 'dist/admin'); 16 | script('settings', 'apps'); 17 | script('external', 'templates'); 18 | 19 | /** @var array $_ */ 20 | /** @var \OCP\IL10N $l */ 21 | ?> 22 |
    23 |
    24 |

    t('External sites'));?>

    25 |

    t('Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites.')); ?>

    26 |

    t('The placeholders {email}, {uid}, {displayname}, {groups}, {language} and {locale} can be used and are filled with the user´s values to customize the links.')); ?>

    27 |

    t('When accessing the external site through the Nextcloud link, path parameters will be forwarded to the external site. So you can also create deep links (e.g. "mycloud.com/external/1/pageA" will lead to Nextcloud with the iframe pointed at "externalsite.com/pageA").')); ?>

    28 |

    ', ' ↗'], 31 | $l->t('A JSON Web Token containing user´s email, uid and display name in its payload can be embedded into the link using the {jwt} placeholder. See the {linkstart}documentation{linkend} how to decode it.') 32 | )); ?>

    33 | 34 |
    35 | 36 |
      37 | 38 | 39 | 40 | 43 | 44 |

      45 | t('Please note that some browsers will block displaying of sites via HTTP if you are running HTTPS.')); ?> 46 |
      47 | t('Furthermore please note that many sites these days disallow iframing due to security reasons.')); ?> 48 |
      49 | t('We highly recommend to test the configured sites above properly.')); ?> 50 |

      51 |
      52 | 53 |
      54 |

      t('Icons'));?>

      55 | 56 |

      57 | t('If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps.')); ?> 58 | t('Uploading an icon with the same name will replace the current icon.')); ?> 59 |

      60 | 61 |
        62 |
      63 | 64 |
      65 | 66 | 72 | 73 |
      74 |
      75 |
      76 | -------------------------------------------------------------------------------- /l10n/ko.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "아이콘 선택", 5 | "All languages" : "모든 언어", 6 | "Header" : "머리글", 7 | "Setting menu" : "설정 메뉴", 8 | "User quota" : "사용자 할당량", 9 | "Public footer" : "공개 바닥글", 10 | "All devices" : "모든 장치", 11 | "Only in the Android app" : "Android 앱만", 12 | "Only in the iOS app" : "iOS 앱만", 13 | "Only in the desktop client" : "데스크톱 클라이언트만", 14 | "Only in the browser" : "브라우저만", 15 | "The given label is invalid" : "지정한 레이블이 잘못됨", 16 | "The given URL is invalid" : "지정한 URL이 잘못됨", 17 | "The given language does not exist" : "지정한 언어가 존재하지 않음", 18 | "The given type is invalid" : "지정한 형식이 잘못됨", 19 | "The given device is invalid" : "지정한 장치가 잘못됨", 20 | "At least one of the given groups does not exist" : "최소한 하나의 지정한 그룹이 존재하지 않음", 21 | "The given icon does not exist" : "지정한 아이콘이 존재하지 않음", 22 | "The site does not exist" : "사이트가 존재하지 않음", 23 | "No file uploaded" : "업로드한 파일 없음", 24 | "Provided file is not an image" : "지정한 파일이 사진이 아님", 25 | "Provided image is not a square of 16, 24 or 32 pixels width" : "지정한 사진이 16, 24, 32픽셀 정사각형이 아님", 26 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "아이콘을 업로드하는 중 오류 발생, 데이터 디렉터리에 쓰기 권한이 있는지 확인하십시오", 27 | "External sites" : "외부 사이트", 28 | "__language_name__" : "한국어", 29 | "Add external sites to your Nextcloud navigation" : "Nextcloud 탐색에 외부 사이트 추가", 30 | "This application allows an admin to add additional links into the Nextcloud menus.\nFollowing a link, the external website appears in the Nextcloud frame.\nIt is also possible to add links only for a given language, device type or user group.\n\nMore information is available in the External sites documentation." : "이 앱을 사용하여 관리자가 Nextcloud 메뉴에 추가 링크를 추가할 수 있습니다.\n해당 링크를 누르면 외부 웹 사이트를 Nextcloud 프레임에 표시합니다.\n언어별, 장치 종류별, 사용자 그룹별로 링크를 추가할 수 있습니다.\n\n더 많은 정보를 보려면 외부 사이트 문서를 참조하십시오.", 31 | "Name" : "이름", 32 | "URL" : "URL", 33 | "Language" : "언어", 34 | "Groups" : "그룹", 35 | "Devices" : "장치", 36 | "Icon" : "아이콘", 37 | "Position" : "위치", 38 | "Redirect" : "넘겨주기", 39 | "Remove site" : "사이트 삭제", 40 | "This site does not allow embedding" : "이 사이트에서 임베딩을 허용하지 않음", 41 | "New site" : "새 사이트", 42 | "Delete icon" : "아이콘 삭제", 43 | "Uploading…" : "업로드 중…", 44 | "Reloading icon list…" : "아이콘 목록을 새로 고치는 중…", 45 | "Icon could not be uploaded" : "아이콘을 업로드할 수 없음", 46 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "웹 사이트를 상단 표시줄의 앱 목록에 바로 추가합니다. 모든 사용자가 볼 수 있으며 다른 내부 웹 앱이나 웹 사이트에 빠르게 접근할 수 있도록 합니다.", 47 | "Please note that some browsers will block displaying of sites via HTTP if you are running HTTPS." : "HTTPS를 사용하는 경우 일부 브라우저에서는 HTTP를 통한 사이트는 표시되지 않을 수 있습니다.", 48 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "또한 많은 웹 사이트에서 보안상의 이유로 iframe 사용을 금지하고 있습니다.", 49 | "We highly recommend to test the configured sites above properly." : "설정한 사이트가 올바르게 작동하는지 테스트하는 것을 추천합니다.", 50 | "Icons" : "아이콘", 51 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "test.png, test-dark.png 파일을 업로드하면 두 파일을 하나의 아이콘으로 사용합니다. 모바일 장치에서는 어두운 버전을 사용하며, 사용할 수 없는 경우에는 흰색 아이콘이 모바일 앱의 흰색 배경에서 보이지 않을 수도 있습니다.", 52 | "Uploading an icon with the same name will replace the current icon." : "같은 이름의 아이콘을 새로 업로드하면 현재 아이콘을 대체합니다.", 53 | "Upload new icon" : "새 아이콘 업로드" 54 | }, 55 | "nplurals=1; plural=0;"); 56 | -------------------------------------------------------------------------------- /l10n/ka_GE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "აირჩიეთ პიქტოგრამა", 3 | "All languages" : "ყველა ენა", 4 | "Header" : "დასათაურება", 5 | "Setting menu" : "პარამეტრის მენიუ", 6 | "User quota" : "მომხმარებლის კვოტა", 7 | "All devices" : "ყველა მოწყობილობა", 8 | "Only in the Android app" : "მხოლოდ Android აპლიკაციაში", 9 | "Only in the iOS app" : "მხოლოდ iOS აპლიკაციაში", 10 | "Only in the desktop client" : "მხოლოდ დესკტოპ-კლიენტში", 11 | "Only in the browser" : "მხოლოდ ბრაუზერში", 12 | "The given label is invalid" : "მოცემული ლეიბლი მიუღებელია", 13 | "The given URL is invalid" : "მოცემული URL არასწორია", 14 | "The given language does not exist" : "მოცემული ენა არ არსებობს", 15 | "The given type is invalid" : "მოცემული სახეობა არასწორია", 16 | "The given device is invalid" : "მოცემული მოწყობილობა არასწორია", 17 | "At least one of the given groups does not exist" : "მოცემული ჯგუფებიდან ერთიც კი არ არსებობს", 18 | "The given icon does not exist" : "მოცემული პიქტოგრამა არ არსებობს", 19 | "The site does not exist" : "საიტი არ არსებობს", 20 | "No file uploaded" : "არც ერთი ფაილი არ ატვირთულა", 21 | "Provided file is not an image" : "მოცემული ფაილი არაა სურათი", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "მოცემული სურათი არაა 16-ის, 24-ის ან 32 პიქსელის სიგანის მქონე კვადრატი", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "პიქტოგრამის ატვირთვისას წარმოიშვა შეცდომა, გთხოვთ დარწმუნდეთ, რომ მონაცემების დირექტორია წერადია", 24 | "External sites" : "გარე საიტები", 25 | "__language_name__" : "ქართული", 26 | "Name" : "სახელი", 27 | "URL" : "URL", 28 | "Language" : "ენა", 29 | "Groups" : "ჯგუფები", 30 | "Devices" : "მოწყობილობები", 31 | "Icon" : "პიქტოგრამა", 32 | "Position" : "პოზიცია", 33 | "Redirect" : "გადამისამართება", 34 | "Remove site" : "საიტის წაშლა", 35 | "This site does not allow embedding" : "ეს საიტი არ იძლევა თან-ჩართვის უფლებას", 36 | "New site" : "ახალი საიტი", 37 | "Delete icon" : "პიქტოგრამის გაუქმება", 38 | "Uploading…" : "იტვირთება...", 39 | "Reloading icon list…" : "პიქტოგრამების სია ნახლდება...", 40 | "Icon could not be uploaded" : "პიქტოგრამა ვერ აიტვირთა", 41 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "აპლიკაციის სიას დაუმატეთ ვებ-საიტი პირდაპირ ზედა ბარში. ეს გამოჩნდება ყველა მომხმარებელთან და დაგეხმარებათ სწრაფი წვდომა იქონიოთ სხვა შიდა გამოყენებულ ვებ-აპლიკაციებთან ან მნიშვნელოვან საიტებთან.", 42 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "ასევე მიაქციათ ყურადღება იმას, რომ მრავალი საიტი დღევანდელ დღეს უსაფრთხოების მიზნით iframe-ის გამოყენების უფლებას არ მოგცემთ.", 43 | "We highly recommend to test the configured sites above properly." : "ჩვენი რეკომენდაცია იქნება, ზედმიწევნით შამოწმოთ ზემოთ კონფიგურირებული საიტები.", 44 | "Icons" : "პიქტოგრამები", 45 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "თუ ატვირთავთ test.png-ს და test-dark.png ფაილებს, ორივე გამოყენებული იქნება ერთ პიქტოგრამად. მუქი ვერსია გამოყენებულ იქნება მობილურებისთვის, სხვა შემთხვევაში თეთრი პიქტოგრამა მობილურ აპლიკაციებში, თეთრ ფონზე, ხილვადი არ იქნება.", 46 | "Uploading an icon with the same name will replace the current icon." : "პიქტოგრამის ატვირთვა იგივე სახელით ჩაანაცვლებს არსებულს.", 47 | "Upload new icon" : "ახალი პიქტოგრამის ატვირთვა" 48 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 49 | } -------------------------------------------------------------------------------- /l10n/ka_GE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "აირჩიეთ პიქტოგრამა", 5 | "All languages" : "ყველა ენა", 6 | "Header" : "დასათაურება", 7 | "Setting menu" : "პარამეტრის მენიუ", 8 | "User quota" : "მომხმარებლის კვოტა", 9 | "All devices" : "ყველა მოწყობილობა", 10 | "Only in the Android app" : "მხოლოდ Android აპლიკაციაში", 11 | "Only in the iOS app" : "მხოლოდ iOS აპლიკაციაში", 12 | "Only in the desktop client" : "მხოლოდ დესკტოპ-კლიენტში", 13 | "Only in the browser" : "მხოლოდ ბრაუზერში", 14 | "The given label is invalid" : "მოცემული ლეიბლი მიუღებელია", 15 | "The given URL is invalid" : "მოცემული URL არასწორია", 16 | "The given language does not exist" : "მოცემული ენა არ არსებობს", 17 | "The given type is invalid" : "მოცემული სახეობა არასწორია", 18 | "The given device is invalid" : "მოცემული მოწყობილობა არასწორია", 19 | "At least one of the given groups does not exist" : "მოცემული ჯგუფებიდან ერთიც კი არ არსებობს", 20 | "The given icon does not exist" : "მოცემული პიქტოგრამა არ არსებობს", 21 | "The site does not exist" : "საიტი არ არსებობს", 22 | "No file uploaded" : "არც ერთი ფაილი არ ატვირთულა", 23 | "Provided file is not an image" : "მოცემული ფაილი არაა სურათი", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "მოცემული სურათი არაა 16-ის, 24-ის ან 32 პიქსელის სიგანის მქონე კვადრატი", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "პიქტოგრამის ატვირთვისას წარმოიშვა შეცდომა, გთხოვთ დარწმუნდეთ, რომ მონაცემების დირექტორია წერადია", 26 | "External sites" : "გარე საიტები", 27 | "__language_name__" : "ქართული", 28 | "Name" : "სახელი", 29 | "URL" : "URL", 30 | "Language" : "ენა", 31 | "Groups" : "ჯგუფები", 32 | "Devices" : "მოწყობილობები", 33 | "Icon" : "პიქტოგრამა", 34 | "Position" : "პოზიცია", 35 | "Redirect" : "გადამისამართება", 36 | "Remove site" : "საიტის წაშლა", 37 | "This site does not allow embedding" : "ეს საიტი არ იძლევა თან-ჩართვის უფლებას", 38 | "New site" : "ახალი საიტი", 39 | "Delete icon" : "პიქტოგრამის გაუქმება", 40 | "Uploading…" : "იტვირთება...", 41 | "Reloading icon list…" : "პიქტოგრამების სია ნახლდება...", 42 | "Icon could not be uploaded" : "პიქტოგრამა ვერ აიტვირთა", 43 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "აპლიკაციის სიას დაუმატეთ ვებ-საიტი პირდაპირ ზედა ბარში. ეს გამოჩნდება ყველა მომხმარებელთან და დაგეხმარებათ სწრაფი წვდომა იქონიოთ სხვა შიდა გამოყენებულ ვებ-აპლიკაციებთან ან მნიშვნელოვან საიტებთან.", 44 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "ასევე მიაქციათ ყურადღება იმას, რომ მრავალი საიტი დღევანდელ დღეს უსაფრთხოების მიზნით iframe-ის გამოყენების უფლებას არ მოგცემთ.", 45 | "We highly recommend to test the configured sites above properly." : "ჩვენი რეკომენდაცია იქნება, ზედმიწევნით შამოწმოთ ზემოთ კონფიგურირებული საიტები.", 46 | "Icons" : "პიქტოგრამები", 47 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "თუ ატვირთავთ test.png-ს და test-dark.png ფაილებს, ორივე გამოყენებული იქნება ერთ პიქტოგრამად. მუქი ვერსია გამოყენებულ იქნება მობილურებისთვის, სხვა შემთხვევაში თეთრი პიქტოგრამა მობილურ აპლიკაციებში, თეთრ ფონზე, ხილვადი არ იქნება.", 48 | "Uploading an icon with the same name will replace the current icon." : "პიქტოგრამის ატვირთვა იგივე სახელით ჩაანაცვლებს არსებულს.", 49 | "Upload new icon" : "ახალი პიქტოგრამის ატვირთვა" 50 | }, 51 | "nplurals=2; plural=(n!=1);"); 52 | -------------------------------------------------------------------------------- /l10n/es_HN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_PA.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (Panama)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_PE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_PR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_PY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_UY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_419.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (México)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /l10n/es_NI.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Select an icon" : "Selecciona un ícono", 3 | "All languages" : "Todos los idiomas", 4 | "Header" : "Encabezado", 5 | "Setting menu" : "Menú de configuración", 6 | "User quota" : "Cuota de usuario", 7 | "All devices" : "Todos los dispositivos", 8 | "Only in the Android app" : "Sólo en la aplicación Android", 9 | "Only in the iOS app" : "Sólo en la aplicación iOS", 10 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 11 | "Only in the browser" : "Sólo en el navegador", 12 | "The given label is invalid" : "La etiqueda dada es inválida", 13 | "The given URL is invalid" : "El URL dado es inválido", 14 | "The given language does not exist" : "El idioma indicado no existe", 15 | "The given type is invalid" : "El tipo indicado es inválido", 16 | "The given device is invalid" : "El dispositivo dado es inválido", 17 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 18 | "The given icon does not exist" : "El ícono indicado no existe", 19 | "The site does not exist" : "El sitio no existe", 20 | "No file uploaded" : "No hay archivos cargados", 21 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 22 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 23 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 24 | "External sites" : "Sitios externos", 25 | "__language_name__" : "Español (Nicaragua)", 26 | "Name" : "Nombre", 27 | "URL" : "URL", 28 | "Language" : "Idioma", 29 | "Groups" : "Grupos", 30 | "Devices" : "Dispositivos", 31 | "Icon" : "Ícono", 32 | "Position" : "Posición", 33 | "Redirect" : "Redirigir", 34 | "Remove site" : "Eliminar sitio", 35 | "New site" : "Nuevo sitio", 36 | "Delete icon" : "Borrar ícono", 37 | "Uploading…" : "Cargando...", 38 | "Reloading icon list…" : "Recargando la lista de íconos...", 39 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 40 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 41 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 42 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 43 | "Icons" : "Íconos", 44 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 45 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 46 | "Upload new icon" : "Cargar nuevo ícono" 47 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 48 | } -------------------------------------------------------------------------------- /lib/Controller/SiteController.php: -------------------------------------------------------------------------------- 1 | 5 | * @license GNU AGPL version 3 or any later version 6 | * 7 | * SPDX-FileCopyrightText: 2017 Joas Schilling 8 | * SPDX-License-Identifier: AGPL-3.0-or-later 9 | */ 10 | 11 | namespace OCA\External\Controller; 12 | 13 | use OCA\External\Exceptions\SiteNotFoundException; 14 | use OCA\External\SitesManager; 15 | use OCP\AppFramework\Controller; 16 | use OCP\AppFramework\Http\ContentSecurityPolicy; 17 | use OCP\AppFramework\Http\RedirectResponse; 18 | use OCP\AppFramework\Http\TemplateResponse; 19 | use OCP\IConfig; 20 | use OCP\IL10N; 21 | use OCP\INavigationManager; 22 | use OCP\IRequest; 23 | use OCP\IURLGenerator; 24 | 25 | class SiteController extends Controller { 26 | protected IConfig $config; 27 | protected SitesManager $sitesManager; 28 | protected INavigationManager $navigationManager; 29 | protected IURLGenerator $url; 30 | protected IL10N $l10n; 31 | 32 | public function __construct(string $appName, 33 | IRequest $request, 34 | IConfig $config, 35 | INavigationManager $navigationManager, 36 | SitesManager $sitesManager, 37 | IURLGenerator $url, 38 | IL10N $l10n) { 39 | parent::__construct($appName, $request); 40 | $this->config = $config; 41 | $this->sitesManager = $sitesManager; 42 | $this->navigationManager = $navigationManager; 43 | $this->url = $url; 44 | $this->l10n = $l10n; 45 | } 46 | 47 | /** 48 | * @NoAdminRequired 49 | * @NoCSRFRequired 50 | */ 51 | public function showPage(int $id, string $path): TemplateResponse|RedirectResponse { 52 | try { 53 | $site = $this->sitesManager->getSiteById($id); 54 | return $this->createResponse($id, $site, $path); 55 | } catch (SiteNotFoundException $e) { 56 | return new RedirectResponse($this->url->linkToDefaultPageUrl()); 57 | } 58 | } 59 | 60 | /** 61 | * @NoAdminRequired 62 | * @NoCSRFRequired 63 | * 64 | * This is used when the app is set as default app 65 | */ 66 | public function showDefaultPage(): TemplateResponse|RedirectResponse { 67 | // Show first available page when there is one 68 | $sites = $this->sitesManager->getSitesToDisplay(); 69 | if (!empty($sites)) { 70 | reset($sites); 71 | $id = key($sites); 72 | return $this->createResponse($id, $sites[$id]); 73 | } 74 | 75 | // Redirect to default page when it's not the external sites app 76 | if ($this->config->getSystemValue('defaultapp', 'files') !== 'external') { 77 | return new RedirectResponse($this->url->linkToDefaultPageUrl()); 78 | } 79 | 80 | // Fall back to the files app 81 | if ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true 82 | || getenv('front_controller_active') === 'true') { 83 | return new RedirectResponse($this->url->getAbsoluteURL('/apps/files/')); 84 | } 85 | return new RedirectResponse($this->url->getAbsoluteURL('/index.php/apps/files/')); 86 | } 87 | 88 | protected function createResponse(int $id, array $site, string $path = ''): TemplateResponse { 89 | $this->navigationManager->setActiveEntry('external_index' . $id); 90 | 91 | if ($path !== '') { 92 | // Check whether we need to suffix the site URL with a slash, or not. 93 | $path = $site['url'][-1] == '/' ? $path : '/' . $path; 94 | } 95 | 96 | $response = new TemplateResponse('external', 'frame', [ 97 | 'url' => $site['url'] . $path, 98 | 'name' => $site['name'], 99 | ], 'user'); 100 | 101 | $policy = new ContentSecurityPolicy(); 102 | $policy->addAllowedWorkerSrcDomain('*'); 103 | $policy->addAllowedFrameDomain('*'); 104 | $policy->addAllowedFrameDomain('blob:'); 105 | $response->setContentSecurityPolicy($policy); 106 | 107 | return $response; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /l10n/es_419.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_HN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_NI.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (Nicaragua)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_PA.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (Panama)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_PE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_PR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_PY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | -------------------------------------------------------------------------------- /l10n/es_UY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "external", 3 | { 4 | "Select an icon" : "Selecciona un ícono", 5 | "All languages" : "Todos los idiomas", 6 | "Header" : "Encabezado", 7 | "Setting menu" : "Menú de configuración", 8 | "User quota" : "Cuota de usuario", 9 | "All devices" : "Todos los dispositivos", 10 | "Only in the Android app" : "Sólo en la aplicación Android", 11 | "Only in the iOS app" : "Sólo en la aplicación iOS", 12 | "Only in the desktop client" : "Sólo en el cliente de escritorio", 13 | "Only in the browser" : "Sólo en el navegador", 14 | "The given label is invalid" : "La etiqueda dada es inválida", 15 | "The given URL is invalid" : "El URL dado es inválido", 16 | "The given language does not exist" : "El idioma indicado no existe", 17 | "The given type is invalid" : "El tipo indicado es inválido", 18 | "The given device is invalid" : "El dispositivo dado es inválido", 19 | "At least one of the given groups does not exist" : "Al menos uno de los grupos dados no existe", 20 | "The given icon does not exist" : "El ícono indicado no existe", 21 | "The site does not exist" : "El sitio no existe", 22 | "No file uploaded" : "No hay archivos cargados", 23 | "Provided file is not an image" : "El archivo proporcionado no es una imagen", 24 | "Provided image is not a square of 16, 24 or 32 pixels width" : "La imagen proporcionada no es un cuadrato de 16, 24 ó 32 pixeles de lado ", 25 | "An error occurred while uploading the icon, please make sure the data directory is writable" : "Se presentó un error al cargar el ícono, por favor asegurate de que se pueda escribir al directorio de datos ", 26 | "External sites" : "Sitios externos", 27 | "__language_name__" : "Español (México)", 28 | "Name" : "Nombre", 29 | "URL" : "URL", 30 | "Language" : "Idioma", 31 | "Groups" : "Grupos", 32 | "Devices" : "Dispositivos", 33 | "Icon" : "Ícono", 34 | "Position" : "Posición", 35 | "Redirect" : "Redirigir", 36 | "Remove site" : "Eliminar sitio", 37 | "New site" : "Nuevo sitio", 38 | "Delete icon" : "Borrar ícono", 39 | "Uploading…" : "Cargando...", 40 | "Reloading icon list…" : "Recargando la lista de íconos...", 41 | "Icon could not be uploaded" : "El ícono no pudo ser cargado", 42 | "Add a website directly to the app list in the top bar. This will be visible for all users and is useful to quickly reach other internally used web apps or important sites." : "Agrega un sitio web directamente a la lista de la aplicación en la barra superiror. Esto será visible para todos los usuarios y es útil para llegar rápidamente a otras aplicaciones web usadas internamente o sitios importantes. ", 43 | "Furthermore please note that many sites these days disallow iframing due to security reasons." : "Adicionalmente, por favor considera que actualmente muchos sitios no permiten el uso de iframes debido temas de seguridad. ", 44 | "We highly recommend to test the configured sites above properly." : "Te recomendamos ámpliamente probar debidamente los sitios configurados anteriormente. ", 45 | "Icons" : "Íconos", 46 | "If you upload a test.png and a test-dark.png file, both will be used as one icon. The dark version will be used on mobile devices, otherwise the white icon is not visible on the white background in the mobile apps." : "Si cargas un archivo test.png y uno test-dark.png, ambos serán usados como un único ícono. La versión obscura será usada en los dispositivos móviles, de lo contrario los íconos claros no son visibles en los fondos claros de estos dispositivos. ", 47 | "Uploading an icon with the same name will replace the current icon." : "Cargar un ícono con el mismo nombre reemplazará el ícono actual.", 48 | "Upload new icon" : "Cargar nuevo ícono" 49 | }, 50 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 51 | --------------------------------------------------------------------------------