263 Commits

Author SHA1 Message Date
El RIDO
b2ef205411 extended script to test jdenticon ImageMagick and documented option to work without GD 2022-11-07 19:42:20 +01:00
El RIDO
c0758e7bbb correct labels, Jdenticon renders PNG or SVG, both in pure PHP 2022-11-07 19:09:16 +01:00
El RIDO
89d575ace3 in light of the perf/size test results of Jdenticons, switch back to Identicons as the default 2022-10-30 09:24:35 +01:00
El RIDO
1892264cf0 add perf/size test for Jdenticons 2022-10-30 09:04:27 +01:00
El RIDO
f5332ee6ff Merge pull request #1005 from PrivateBin/crowdin-translation
New Crowdin updates
2022-10-29 15:07:46 +02:00
PrivateBin Translator Bot
e39a2eeb61 New translations en.json (Corsican) 2022-10-29 13:09:30 +02:00
El RIDO
405067668a Merge pull request #1004 from PrivateBin/dependabot/composer/phpunit/phpunit-5.6.3
Bump phpunit/phpunit from 5.2.7 to 5.6.3
2022-10-29 08:17:33 +02:00
dependabot[bot]
922feb2779 Bump phpunit/phpunit from 5.2.7 to 5.6.3
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 5.2.7 to 5.6.3.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-8.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/5.2.7...5.6.3)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-29 06:07:06 +00:00
El RIDO
968d7a19bf Merge pull request #1001 from PrivateBin/jdenticon
add new Jdenticon comment icon library and set it as default
2022-10-29 08:06:43 +02:00
El RIDO
795c030bdb Revert several commits that didn't solve the Scrutinizer issues 2022-10-26 08:16:30 +02:00
El RIDO
613e4e9d57 custom php-cs doesn't support website config on Scrutinizer 2022-10-26 08:11:35 +02:00
El RIDO
c91d20ae75 try using the updated php-cs dependency on Scrutinizer 2022-10-26 08:03:55 +02:00
El RIDO
d5104a1d63 Merge pull request #1000 from PrivateBin/set-output-deprecation
handle github actions deprecation warnings
2022-10-26 07:57:33 +02:00
El RIDO
78b3630eb5 try updating that borked php-cs dependency on Scrutinizer 2022-10-26 07:55:26 +02:00
El RIDO
31f75ee138 undo accidental PHP 8 induced upgrade of php-timer, making it incompatible with PHP 7 used on Scrutinizer 2022-10-26 07:39:35 +02:00
El RIDO
ae3a0b19ee update PHP version used in Scrutinizer CI to 7.4, fixing php-timer requirement 2022-10-26 07:23:37 +02:00
El RIDO
d5e7e6e2ab document Jdenticon change 2022-10-26 07:11:02 +02:00
El RIDO
8ac69590cf add new Jdenticon comment icon library, set it as default, fixes #793 2022-10-26 06:53:56 +02:00
El RIDO
ba4878056b misleading documentation 2022-10-26 05:51:36 +02:00
El RIDO
ae6248e27e handle github actions deprecation warnings
see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
2022-10-26 05:48:51 +02:00
El RIDO
78aa70e3ab Merge pull request #999 from PrivateBin/php82-deprecated-callables
PHP 8.2 compatibility: Use of "self" in callables is deprecated
2022-10-26 04:39:11 +02:00
El RIDO
670f9ef548 Merge pull request #998 from PrivateBin/crowdin-translation
New Crowdin updates
2022-10-25 21:11:30 +02:00
PrivateBin Translator Bot
1a828884d1 New translations en.json (Hungarian) 2022-10-25 21:01:18 +02:00
PrivateBin Translator Bot
18a957ee54 New translations en.json (Hebrew) 2022-10-25 21:01:17 +02:00
El RIDO
8f8adb9b0d Merge branch 'master' into crowdin-translation 2022-10-25 20:27:22 +02:00
PrivateBin Translator Bot
c3041924b6 New translations en.json (Occitan) 2022-10-25 20:03:32 +02:00
PrivateBin Translator Bot
5584fdb347 New translations en.json (Chinese Simplified) 2022-10-25 20:03:31 +02:00
PrivateBin Translator Bot
ec75ef6e36 New translations en.json (Ukrainian) 2022-10-25 20:03:30 +02:00
PrivateBin Translator Bot
b1f24a51c8 New translations en.json (Turkish) 2022-10-25 20:03:29 +02:00
PrivateBin Translator Bot
60b091d0e1 New translations en.json (Slovak) 2022-10-25 20:03:28 +02:00
PrivateBin Translator Bot
ed5859c6b6 New translations en.json (Russian) 2022-10-25 20:03:27 +02:00
PrivateBin Translator Bot
cd0a7effa0 New translations en.json (Portuguese) 2022-10-25 20:03:25 +02:00
PrivateBin Translator Bot
ab3e8ffd49 New translations en.json (Norwegian) 2022-10-25 20:03:24 +02:00
PrivateBin Translator Bot
7269755bc2 New translations en.json (Dutch) 2022-10-25 20:03:23 +02:00
PrivateBin Translator Bot
5e48a927f2 New translations en.json (Lithuanian) 2022-10-25 20:03:22 +02:00
El RIDO
bff4d3a016 PHP 8.2 compatibility: Use of "self" in callables is deprecated 2022-10-25 07:15:09 +02:00
PrivateBin Translator Bot
2eab8adcd1 New translations en.json (Corsican) 2022-10-25 07:05:13 +02:00
PrivateBin Translator Bot
92c42afdc7 New translations en.json (Arabic) 2022-10-25 07:05:12 +02:00
PrivateBin Translator Bot
da48f8a9a1 New translations en.json (Bulgarian) 2022-10-25 07:05:11 +02:00
PrivateBin Translator Bot
7b40893497 New translations en.json (Catalan) 2022-10-25 07:05:10 +02:00
PrivateBin Translator Bot
0a1fccea11 New translations en.json (Czech) 2022-10-25 07:05:09 +02:00
PrivateBin Translator Bot
3de21004c4 New translations en.json (German) 2022-10-25 07:05:07 +02:00
PrivateBin Translator Bot
d0d0621bac New translations en.json (Greek) 2022-10-25 07:05:05 +02:00
PrivateBin Translator Bot
3845298804 New translations en.json (Finnish) 2022-10-25 07:05:04 +02:00
PrivateBin Translator Bot
d6c5f97d58 New translations en.json (Hebrew) 2022-10-25 07:05:03 +02:00
PrivateBin Translator Bot
f713b92893 New translations en.json (Hungarian) 2022-10-25 07:05:01 +02:00
PrivateBin Translator Bot
f254285b01 New translations en.json (Italian) 2022-10-25 07:05:00 +02:00
PrivateBin Translator Bot
c2d5c6fc43 New translations en.json (Japanese) 2022-10-25 07:04:59 +02:00
PrivateBin Translator Bot
3d4f9cc1b3 New translations en.json (Kurdish) 2022-10-25 07:04:58 +02:00
PrivateBin Translator Bot
945435e133 New translations en.json (Lithuanian) 2022-10-25 07:04:57 +02:00
PrivateBin Translator Bot
d288f2ab73 New translations en.json (Dutch) 2022-10-25 07:04:56 +02:00
PrivateBin Translator Bot
7ab3f3f271 New translations en.json (Spanish) 2022-10-25 07:04:54 +02:00
PrivateBin Translator Bot
019c8b64b8 New translations en.json (Norwegian) 2022-10-25 07:04:53 +02:00
PrivateBin Translator Bot
06b01c57ac New translations en.json (Portuguese) 2022-10-25 07:04:52 +02:00
PrivateBin Translator Bot
b756da5839 New translations en.json (Russian) 2022-10-25 07:04:51 +02:00
PrivateBin Translator Bot
8a9761b430 New translations en.json (Slovak) 2022-10-25 07:04:50 +02:00
PrivateBin Translator Bot
79c4ace626 New translations en.json (Slovenian) 2022-10-25 07:04:49 +02:00
PrivateBin Translator Bot
534d014254 New translations en.json (Swedish) 2022-10-25 07:04:48 +02:00
PrivateBin Translator Bot
40a037b625 New translations en.json (Turkish) 2022-10-25 07:04:47 +02:00
PrivateBin Translator Bot
5cb40e1f9e New translations en.json (Ukrainian) 2022-10-25 07:04:46 +02:00
PrivateBin Translator Bot
c9144def9f New translations en.json (Chinese Simplified) 2022-10-25 07:04:45 +02:00
PrivateBin Translator Bot
989fe6cc3a New translations en.json (Indonesian) 2022-10-25 07:04:44 +02:00
PrivateBin Translator Bot
08ac373b12 New translations en.json (Estonian) 2022-10-25 07:04:42 +02:00
PrivateBin Translator Bot
c2ec38e0a3 New translations en.json (Hindi) 2022-10-25 07:04:41 +02:00
PrivateBin Translator Bot
f31e384980 New translations en.json (Lojban) 2022-10-25 07:04:39 +02:00
PrivateBin Translator Bot
a1b4fcdefb New translations en.json (Latin) 2022-10-25 07:04:39 +02:00
PrivateBin Translator Bot
09902b9d67 New translations en.json (Occitan) 2022-10-25 07:04:38 +02:00
PrivateBin Translator Bot
f8bb6efcf9 New translations en.json (Polish) 2022-10-25 07:04:37 +02:00
PrivateBin Translator Bot
930063442a New translations en.json (French) 2022-10-25 07:04:35 +02:00
El RIDO
849c1c7cd1 fix display of configured name in twitter title 2022-10-25 06:34:40 +02:00
PrivateBin Translator Bot
5e513588db New translations en.json (German) 2022-10-25 06:08:09 +02:00
PrivateBin Translator Bot
fef83a37ef New translations en.json (Slovak) 2022-10-23 22:46:25 +02:00
El RIDO
4f9af21fb2 Merge pull request #997 from jmozd/serverside_yourls
Serverside yourls
2022-10-23 18:03:14 +02:00
El RIDO
a66f170c5e PHP 5.6 seems to tolerate an empty string as valid JSON 2022-10-23 13:21:22 +02:00
El RIDO
44f78ffcdf apply StyleCI recommendations 2022-10-23 13:14:27 +02:00
El RIDO
2776033997 apply StyleCI recommendations 2022-10-23 13:13:12 +02:00
El RIDO
0a949d3903 credit change, document it and improve wording 2022-10-23 13:10:55 +02:00
El RIDO
78e915e049 adding tests for YOURLS functionality 2022-10-23 13:09:54 +02:00
El RIDO
4bd5ef9cda add new messages to translate 2022-10-23 10:50:18 +02:00
El RIDO
69034ef9d1 apply StyleCI recommendations 2022-10-23 09:16:55 +02:00
El RIDO
2a162d075c allow unit tests to pass 2022-10-23 09:12:31 +02:00
El RIDO
f4000150fa avoid cURL dependency, native functions should suffice for such a simple call 2022-10-23 09:05:17 +02:00
El RIDO
b768a2e8cb use JSON wrapper for decoding error catching 2022-10-23 08:21:37 +02:00
El RIDO
0a2094f069 code style 2022-10-23 08:16:05 +02:00
El RIDO
0dc9ab7576 refactor shortenviayourls.php for our MVC framework 2022-10-23 08:10:56 +02:00
El RIDO
304ae76a04 Merge branch 'serverside_yourls' of https://github.com/jmozd/PrivateBin into serverside_yourls 2022-10-23 05:43:18 +02:00
El RIDO
13b4dc79b9 Merge pull request #992 from PrivateBin/zlib-1.2.13
update zlib to 1.2.13
2022-10-23 05:14:15 +02:00
El RIDO
9d07e68e7d Merge branch 'master' into zlib-1.2.13 2022-10-23 05:06:50 +02:00
Jens-U. Mozdzen
dce8b8d352 updated code formatting 2022-10-23 01:07:43 +02:00
Jens-U. Mozdzen
3115cb8883 added parameters for server-side YOURLS shortener call 2022-10-23 00:19:43 +02:00
Jens-U. Mozdzen
b0f17f0a91 added server-side YOURLS shortener call 2022-10-23 00:18:56 +02:00
El RIDO
a36351ca37 Merge pull request #994 from felixjogris/s3backend
implemented S3 storage backend
2022-10-22 18:35:03 +02:00
Felix J. Ogris
ee212b1a33 implemented S3 storage backend
added sample configuration + aws php sdk version

coding style cleanup
2022-10-22 18:30:24 +02:00
El RIDO
08b6070359 update zlib to 1.2.13 2022-10-15 09:05:19 +02:00
El RIDO
2e2c70ed15 Merge pull request #986 from PrivateBin/crowdin-translation
New Crowdin updates
2022-10-07 07:53:30 +02:00
PrivateBin Translator Bot
38245287d0 New translations en.json (Slovak) 2022-10-07 07:11:45 +02:00
El RIDO
688574f70c Merge pull request #988 from RaJiska/master
GCS Uniform ACL Support
2022-10-07 05:58:54 +02:00
Ra'Jiska
8dbe60621d Fix GCS Upload Metadata Mistake 2022-10-06 14:41:37 +08:00
PrivateBin Translator Bot
23e0000101 New translations en.json (Greek) 2022-10-06 08:30:59 +02:00
PrivateBin Translator Bot
1aa93f7fb2 New translations en.json (Slovak) 2022-10-06 08:30:58 +02:00
Ra'Jiska
8dded4e8e4 GCS Support for Uniform ACL Buckets 2022-10-06 12:19:06 +08:00
PrivateBin Translator Bot
ad6e802e8a New translations en.json (Greek) 2022-10-05 12:30:02 +02:00
PrivateBin Translator Bot
c6659747ae New translations en.json (Greek) 2022-10-05 09:01:55 +02:00
El RIDO
160207b25a Merge pull request #983 from PrivateBin/slovak
enable use of Slovak translations
2022-09-30 05:24:21 +02:00
El RIDO
77409e6065 crediting greek language as well, plus docs 2022-09-29 21:15:00 +02:00
El RIDO
abef3ad37b Merge branch 'master' into slovak 2022-09-29 21:10:50 +02:00
El RIDO
0e630e14b7 Merge pull request #985 from eellak/greek-lang
Update strings in el.json and enable greek language
2022-09-29 21:06:18 +02:00
Christos Karamolegkos
0f1c2fdb04 Update strings in el.json and enable greek language 2022-09-29 15:34:15 +03:00
El RIDO
b61b4253a6 enabled use of Slovak translations 2022-09-29 05:34:49 +02:00
R4SAS
afd84da6b2 Merge pull request #981 from PrivateBin/crowdin-translation
New Crowdin updates
2022-09-26 10:15:30 +00:00
PrivateBin Translator Bot
51f5082f39 New translations en.json (Slovak) 2022-09-25 17:09:10 +02:00
PrivateBin Translator Bot
1b727f7fa4 New translations en.json (Slovak) 2022-09-25 16:12:48 +02:00
El RIDO
4ea2d6020f Merge pull request #979 from PrivateBin/crowdin-translation
New Crowdin updates
2022-09-24 10:05:58 +02:00
PrivateBin Translator Bot
3255a4d954 New translations en.json (Slovak) 2022-09-20 21:21:45 +02:00
PrivateBin Translator Bot
4025619236 New translations en.json (Slovak) 2022-09-20 20:11:36 +02:00
El RIDO
eef9a52b69 Merge pull request #968 from PrivateBin/crowdin-translation
New Crowdin updates
2022-09-18 14:44:56 +02:00
PrivateBin Translator Bot
7580155243 New translations en.json (Slovak) 2022-09-18 14:19:01 +02:00
PrivateBin Translator Bot
49b8312505 New translations en.json (Dutch) 2022-09-18 14:19:00 +02:00
PrivateBin Translator Bot
d1b53360d5 New translations en.json (Slovak) 2022-09-18 13:16:32 +02:00
PrivateBin Translator Bot
e35710ca30 New translations en.json (Turkish) 2022-09-18 13:16:31 +02:00
PrivateBin Translator Bot
123210bb8f New translations en.json (Dutch) 2022-09-18 13:16:30 +02:00
PrivateBin Translator Bot
e11c89ab85 New translations en.json (Czech) 2022-09-16 23:59:49 +02:00
PrivateBin Translator Bot
e56b24fc3b New translations en.json (Turkish) 2022-09-10 22:29:16 +02:00
PrivateBin Translator Bot
76fe7063ca New translations en.json (Dutch) 2022-09-10 22:29:14 +02:00
PrivateBin Translator Bot
fa1e4728dc New translations en.json (Russian) 2022-09-10 21:32:33 +02:00
PrivateBin Translator Bot
d57a849a40 New translations en.json (Dutch) 2022-09-10 21:32:32 +02:00
PrivateBin Translator Bot
d065f42785 New translations en.json (Czech) 2022-09-10 14:08:53 +02:00
PrivateBin Translator Bot
d848ce2ed2 New translations en.json (Ukrainian) 2022-08-30 00:53:01 +02:00
El RIDO
ac06627d9f Merge pull request #971 from PrivateBin/coop-header-disable
Remove COOP header for now
2022-08-24 06:28:09 +02:00
rugk
e740d0f761 Remove COOP header for now
Same as https://github.com/PrivateBin/docker-nginx-fpm-alpine/pull/108

Disable the header here as it breaks links to the own site.
2022-08-22 13:25:56 +02:00
PrivateBin Translator Bot
6e60efc2dd New translations en.json (Dutch) 2022-08-21 17:21:33 +02:00
PrivateBin Translator Bot
a105ba7566 New translations en.json (Turkish) 2022-08-21 17:21:28 +02:00
PrivateBin Translator Bot
67365f8602 New translations en.json (Ukrainian) 2022-08-21 17:21:27 +02:00
El RIDO
628700afb1 Merge pull request #960 from PrivateBin/crowdin-translation
New Crowdin updates
2022-07-23 07:23:55 +02:00
PrivateBin Translator Bot
5c20a424e1 New translations en.json (Lithuanian) 2022-07-22 14:07:48 +02:00
El RIDO
1a5eafe424 Merge pull request #958 from PrivateBin/crowdin-translation
New Crowdin updates
2022-07-16 09:33:14 +02:00
PrivateBin Translator Bot
925f8cb338 New translations en.json (Spanish) 2022-07-14 09:41:47 +02:00
PrivateBin Translator Bot
9e499652be New translations en.json (Spanish) 2022-07-14 08:34:07 +02:00
El RIDO
61efe71e31 Merge pull request #957 from PrivateBin/nodejs-16-tests
Use NodeJs v16 for tests
2022-07-10 10:31:02 +02:00
rugk
48bb2fdf0f Use NodeJs v16 for tests
So 14 worked, let's try 16. (Actually noticed fedora uses v16 not 14 which makes sense if you see the support time.)
2022-07-10 00:13:47 +02:00
El RIDO
b46b4300ec Merge pull request #955 from PrivateBin/node14
chore: run tests with NodeJS 14
2022-07-09 17:45:23 +02:00
El RIDO
67fdd54ae5 Merge pull request #954 from PrivateBin/packagelock
Add missing package-json.lock
2022-07-09 17:41:39 +02:00
rugk
e536db9b7e style: run tests via npm script insread of custom command
I.e. not call mocha directly but let the script defined in package.json do it's job.
2022-07-09 17:04:28 +02:00
rugk
9a476ac34d chore: switch to proper cache file now we have it, i.e. package-lock.json
as per https://github.com/actions/setup-node#caching-global-packages-data
2022-07-09 17:00:45 +02:00
rugk
79fd33d21f chore: run tests with NodeJS 14
I expect no stuff to break or so, so let's just try to use the current recommend LTS version. (v14 will also die at some time, but Fedora e.g. still seems to use it for now by default. Likely we may upgrade soon even more.)

Ref https://nodejs.org/en/about/releases/
2022-07-09 16:57:06 +02:00
rugk
08946d1cab Use npm ci instead of npm install for tests in CI
So it uses the package-json.lock file actually.
2022-07-09 16:48:21 +02:00
rugk
29b8215332 Add missing package-json.lock
NodeJS v16.14.0
2022-07-09 16:44:35 +02:00
El RIDO
f9d78d62a0 Merge pull request #945 from PrivateBin/mysql-index-exists
CREATE INDEX IF NOT EXISTS is not supported as of MySQL <= 8.0
2022-06-30 06:43:36 +02:00
El RIDO
e6d606ba88 clarify that it is only unsupported by Oracle MySQL, while supported in MariaDB, Postgres, SQLite, ... 2022-06-29 22:25:54 +02:00
El RIDO
4ad4aed875 apply table prefix to indexes as well, to support multiple instances sharing a single database 2022-06-28 06:51:21 +02:00
El RIDO
b7cffbddd0 CREATE INDEX IF NOT EXISTS is not supported as of MySQL <= 8.0, fixes #943 2022-06-27 19:05:57 +02:00
El RIDO
9b132f4054 Merge pull request #941 from PrivateBin/dependabot/github_actions/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-06-10 05:04:21 +02:00
El RIDO
e052dd9d83 Merge pull request #940 from PrivateBin/dependabot/github_actions/actions/cache-3
Bump actions/cache from 2 to 3
2022-06-10 05:03:19 +02:00
dependabot[bot]
b6f35fc8ab Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 03:02:26 +00:00
El RIDO
9291e57ac6 Merge pull request #939 from PrivateBin/dependabot/github_actions/github/codeql-action-2
Bump github/codeql-action from 1 to 2
2022-06-10 05:02:04 +02:00
El RIDO
9df0faf7b8 Merge pull request #938 from PrivateBin/dependabot/github_actions/actions/setup-node-3
Bump actions/setup-node from 2 to 3
2022-06-10 05:01:17 +02:00
dependabot[bot]
be23ae2874 Bump actions/cache from 2 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 02:59:25 +00:00
dependabot[bot]
86794be1c4 Bump github/codeql-action from 1 to 2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 02:59:19 +00:00
dependabot[bot]
48a6bf4416 Bump actions/setup-node from 2 to 3
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2 to 3.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-10 02:59:15 +00:00
El RIDO
b75bfc3e34 Merge pull request #937 from PrivateBin/dependabot
Add/enable Dependabot to keep dependencies up-to-date
2022-06-10 04:58:52 +02:00
rugk
3c8c32fbcb Add/enable Dependabot to keep dependencies up-to-date
Enabled update checking via Dependabot for
* GitHub Actions for updates or in case you are going to use that (just my default)
* PHP aka Composer

We successfully use it [for our Docker container](https://github.com/PrivateBin/docker-nginx-fpm-alpine/blob/master/.github/dependabot.yml) and IMHO that has worked quite well, so IMHO, we can also use it here now.
2022-06-09 23:42:03 +02:00
El RIDO
0ebac188a8 Merge pull request #936 from AnonymousWP/master
Add missing Dutch translations
2022-06-08 20:28:52 +02:00
AnonymousWP
dad1c5dc5b Add Dutch translations
Also fixed Dutch spelling and grammar mistakes.
2022-06-08 11:32:16 +02:00
El RIDO
c3302b5f8d Merge pull request #935 from PeGaSuS-Coder/patch-1
Update conf.sample.php
2022-06-06 07:36:21 +02:00
PeGaSuS
f8ff49509b Update conf.sample.php
Fixed typo to match the mysql database name
2022-06-05 18:42:54 +02:00
PeGaSuS
6d748de33a Update conf.sample.php
Added an working PostgreSQL database configuration.
2022-06-05 18:41:09 +02:00
El RIDO
d9857017de Merge pull request #932 from PrivateBin/php-8.1-deprecations
addressing deprecation warnings in php 8.1
2022-06-02 19:21:46 +02:00
El RIDO
07a23d7f0b addressing deprecation warnings in php 8.1
Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in lib/Data/Database.php on line 280 & 555
2022-06-01 21:05:08 +02:00
El RIDO
4487171263 Merge pull request #926 from PrivateBin/crowdin-translation
New Crowdin updates
2022-05-02 19:21:58 +02:00
PrivateBin Translator Bot
3ae97cde7a New translations en.json (Catalan) 2022-05-02 00:14:26 +02:00
El RIDO
e1b5d277c7 Merge pull request #925 from MTBBK/patch-1
Update tr.json
2022-04-30 09:45:20 +02:00
El RIDO
c065a4b739 Merge pull request #924 from PrivateBin/enable-turkish
Enable Turkish translation
2022-04-30 09:22:47 +02:00
MTBBK
b6fc4bd19d Update tr.json 2022-04-28 23:00:31 +03:00
El RIDO
f717334ee0 - credit & document Turkish translation
- remove plural indicators
- add plural logic and enable Turkish translation
2022-04-28 20:05:57 +02:00
El RIDO
2c01892ee1 bump github/codeql-action from 1 to 2 2022-04-28 19:47:28 +02:00
El RIDO
14440630bb Merge pull request #923 from rahmanlar/patch-1
Update Turkish localization
2022-04-28 19:44:23 +02:00
Emir Ensar Rahmanlar
b023351991 Update Turkish localization 2022-04-28 11:37:27 +03:00
El RIDO
d0142c31cc Merge pull request #920 from PrivateBin/mysql_ansi_quotes
Avoid SUPER privilege when setting the sql_mode for MariaDB/MySQL, fixes #919
2022-04-20 19:56:24 +02:00
El RIDO
0e2ec27033 Avoid privilege for setting the for MariaDB/MySQL, fixes #919 2022-04-19 18:44:00 +02:00
El RIDO
a15b395eaf fix php8 refresh workflow
requires updating the commit action due to
https://github.com/github-actions-x/commit/issues/30
2022-04-14 06:19:19 +02:00
El RIDO
15a9b8d826 fix php8 refresh workflow
requires updating the commit action due to
https://github.com/github-actions-x/commit/issues/30
2022-04-14 06:17:10 +02:00
El RIDO
d2126d6dd6 fix php8 refresh workflow
requires updating the commit action due to
https://github.com/github-actions-x/commit/issues/30
2022-04-14 06:08:48 +02:00
El RIDO
62b14ae20f Merge pull request #916 from HLeithner/patch-1
Replace FLoC Header with browsing-topics header
2022-04-11 19:09:00 +02:00
Harald Leithner
4b3d11c988 Add browsing-topics premission policy 2022-04-10 11:28:52 +02:00
El RIDO
81b8620006 Merge pull request #915 from PrivateBin/crowdin-translation
New Crowdin updates
2022-04-10 11:16:18 +02:00
Harald Leithner
7b8e031ab5 Remove FLoC Header
Google announced that it is discontinuing FLoC.
2022-04-10 10:36:39 +02:00
PrivateBin Translator Bot
cdea2917c1 New translations en.json (Chinese Simplified) 2022-04-10 09:43:11 +02:00
El RIDO
38b419945c Merge pull request #914 from imtms/master
Update zh translation
2022-04-09 19:55:59 +02:00
TMs
ba7bcbbb62 update zh translation 2022-04-09 22:42:47 +08:00
El RIDO
7ce853001d Merge branch 'release-1.4' 2022-04-09 14:38:22 +02:00
El RIDO
456ced37c2 incrementing version 2022-04-05 07:30:51 +02:00
El RIDO
3a7350c5c4 reword and reformat documents 2022-04-05 07:28:25 +02:00
El RIDO
f0d0daffcc enable and credit new Finnish translation 2022-04-05 07:22:07 +02:00
El RIDO
21400d4928 Merge pull request #910 from davidnemec/fix-env-name
Fix wrong env name for GCS bucket
2022-04-04 19:12:45 +02:00
David Němec
91d51e075d Fix wrong env name for GCS bucket 2022-04-04 14:17:40 +02:00
El RIDO
bd308a0d3b Merge pull request #909 from PrivateBin/zlib-1.2.12
upgrade to zlib 1.2.12
2022-03-30 20:49:20 +02:00
El RIDO
f2e0c1a701 upgrade to zlib 1.2.12 2022-03-30 06:05:37 +02:00
El RIDO
ffab73a314 Merge pull request #907 from PrivateBin/crowdin-translation
New Crowdin updates
2022-03-28 19:05:27 +02:00
El RIDO
1dd53a93f4 Merge branch 'hardening' 2022-03-28 19:02:35 +02:00
PrivateBin Translator Bot
835fbe0e2f New translations en.json (Finnish) 2022-03-27 10:56:23 +02:00
El RIDO
11b16fc6fd removed directive needed for the PDF preview in FireFox < 78
fixed in https://bugzilla.mozilla.org/show_bug.cgi?id=1582115 and
https://bugzilla.mozilla.org/show_bug.cgi?id=1638826 for FF 78
2022-03-27 08:45:33 +02:00
El RIDO
2b509d0475 Merge branch 'master' into hardening 2022-03-27 08:29:12 +02:00
El RIDO
40d35ab3c2 update SRI-hashes 2022-03-27 08:28:54 +02:00
El RIDO
82be7c6354 Merge branch 'hardening' of github.com:PrivateBin/PrivateBin into hardening 2022-03-27 08:28:10 +02:00
El RIDO
75dc346f0f be more specific on the base type match and less specific on the subtype, in order to fail-safe (avoid being tricked into not sanitizing - the mime type is a user provided input) 2022-03-27 08:27:24 +02:00
El RIDO
960faf4417 wording
Co-authored-by: rugk <rugk+git@posteo.de>
2022-03-27 07:58:25 +02:00
El RIDO
7ad677921b Merge pull request #905 from PrivateBin/crowdin-translation
New Crowdin updates
2022-03-23 20:45:00 +01:00
PrivateBin Translator Bot
b6db556b34 New translations en.json (Finnish) 2022-03-21 19:11:47 +01:00
El RIDO
36cb37c029 prevent error when attachments are disabled, but paste with attachment gets displayed 2022-03-13 20:18:51 +01:00
El RIDO
5617612eb3 upgrade to showdown 2.0.3 2022-03-13 20:05:38 +01:00
El RIDO
2a4d572c1e Sanitize SVG preview, preventing script execution in instance context, while dropping support for attachment download in IE 2022-03-13 19:56:12 +01:00
El RIDO
6c1f0dde0c set CSP also as meta tag, to deal with misconfigured webservers mangling the HTTP header 2022-03-13 18:11:13 +01:00
El RIDO
1807580226 Merge pull request #900 from PrivateBin/crowdin-translation
New Crowdin updates
2022-03-01 06:44:43 +01:00
PrivateBin Translator Bot
cc60ab701b New translations en.json (German) 2022-02-28 19:34:00 +01:00
El RIDO
389b07bd2d Merge pull request #901 from PrivateBin/trafficlimit-short-subnets
Allow short subnet notation
2022-02-28 19:21:45 +01:00
PrivateBin Translator Bot
e9d6996db4 New translations en.json (Italian) 2022-02-28 17:27:05 +01:00
PrivateBin Translator Bot
a58bba0958 New translations en.json (German) 2022-02-28 17:27:04 +01:00
PrivateBin Translator Bot
abaa9eca35 New translations en.json (French) 2022-02-28 17:27:03 +01:00
El RIDO
3e02818335 actually support the short CIDR notation 2022-02-28 16:24:06 +01:00
El RIDO
6b001b5e4a typo 2022-02-28 16:23:11 +01:00
PrivateBin Translator Bot
ccdb26df51 New translations en.json (Corsican) 2022-02-28 12:45:13 +01:00
PrivateBin Translator Bot
bef5c647cf New translations en.json (Occitan) 2022-02-28 11:29:33 +01:00
El RIDO
2b46fdd626 Merge branch 'stevenandres-master' 2022-02-27 19:32:43 +01:00
El RIDO
f83f80b5f6 Merge branch 'master' into stevenandres-master 2022-02-26 11:56:58 +01:00
El RIDO
f39934a104 Merge pull request #896 from Patriccollu/PB-in-Corsican
Adding Corsican as brand new locale
2022-02-26 11:52:43 +01:00
Patriccollu
4c8d23d3a5 Adding co.json for Corsican 2022-02-26 10:35:08 +01:00
El RIDO
fe89161848 replace deprecated function calls 2022-02-26 07:18:59 +01:00
El RIDO
d544d5e763 Update tst/Persistence/TrafficLimiterTest.php
Co-authored-by: rugk <rugk+git@posteo.de>
2022-02-26 06:59:11 +01:00
El RIDO
094c96afc6 Update tst/Persistence/TrafficLimiterTest.php
Co-authored-by: rugk <rugk+git@posteo.de>
2022-02-26 06:59:02 +01:00
El RIDO
247992fbca Update tst/Persistence/TrafficLimiterTest.php
Co-authored-by: rugk <rugk+git@posteo.de>
2022-02-26 06:58:54 +01:00
El RIDO
77153a9b49 Update tst/Persistence/TrafficLimiterTest.php
Co-authored-by: rugk <rugk+git@posteo.de>
2022-02-26 06:58:41 +01:00
Patriccollu
110962bc8e Updating CREDITS.md for new locale Corsican 2022-02-25 13:18:01 +01:00
Patriccollu
d73cfb093c Updating CHANGELOG.md for new locale Corsican 2022-02-25 13:17:50 +01:00
El RIDO
288cf3f005 Merge branch 'master' into stevenandres-master 2022-02-25 06:42:18 +01:00
El RIDO
a62f29f052 Merge branch 'lib-update' 2022-02-25 06:40:56 +01:00
Patriccollu
9b9be50678 Adding co.json for Corsican 2022-02-25 00:02:58 +01:00
Patriccollu
30c0d22468 Updating I18n.php to add Corsican as new locale 2022-02-24 20:05:19 +01:00
Patriccollu
004e2dd75c Update to add Corsican as new locale 2022-02-24 20:03:48 +01:00
Patriccollu
d5d06caf40 Adding co.json for Corsican 2022-02-24 19:50:27 +01:00
El RIDO
7a6f36a789 disable failing part of the test 2022-02-23 06:04:05 +01:00
El RIDO
a0f8a667ae deprecated functions, fix test partially 2022-02-20 21:07:04 +01:00
El RIDO
fbf0eae513 update bootstrap JS library to 3.4.1
note that this fails one of our unit tests
2022-02-20 16:13:54 +01:00
El RIDO
f987e96d4b apply StyleCI recommendation 2022-02-20 12:25:55 +01:00
El RIDO
1054319313 add new translation string 2022-02-20 12:22:34 +01:00
El RIDO
6b59d4f380 document change 2022-02-20 11:51:41 +01:00
El RIDO
1034d4038e unify IP-related logic into traffic limiter 2022-02-20 11:25:19 +01:00
El RIDO
dbe8debe30 add creator unit tests for refactoring target, currently failing 2022-02-20 09:35:05 +01:00
El RIDO
190a35a53b small unit test refactoring, comment wording 2022-02-20 09:30:41 +01:00
El RIDO
91041d8c59 simplify/unify naming & wording of the two types of IP lists for the traffic limiter 2022-02-20 09:09:20 +01:00
El RIDO
d764c03759 Merge branch 'master' of https://github.com/stevenandres/PrivateBin into stevenandres-master 2022-02-20 08:44:09 +01:00
Steven Andrés
3f75c81a2f fixed duplicated getKey() 2020-05-08 12:18:20 -07:00
Steven Andrés
effe6ad3e5 fixed spacing to please StyleCI 2020-05-08 11:37:21 -07:00
Steven Andrés
8fbdb69d8a added check for null whitelist 2020-05-08 11:36:19 -07:00
Steven Andrés
b8594c174a whitelist_paste_creation description 2020-05-07 16:48:17 -07:00
Steven Andrés
d847e2fcf2 alignment 2020-05-07 16:46:31 -07:00
Steven Andrés
c152f85b50 removed $remoteip that the audit didn't like 2020-05-07 16:45:24 -07:00
Steven Andrés
819d25a74c change to whitelist_paste_creation 2020-05-07 16:13:25 -07:00
Steven Andrés
cea96ee12a Update cfg/conf.sample.php
Co-authored-by: rugk <rugk+git@posteo.de>
2020-05-07 15:55:09 -07:00
Steven Andrés
ef9780707a Update lib/Controller.php
Co-authored-by: rugk <rugk+git@posteo.de>
2020-05-07 15:54:13 -07:00
Steven Andrés
9ca041fa06 Update lib/Controller.php
Co-authored-by: rugk <rugk+git@posteo.de>
2020-05-07 15:53:56 -07:00
Steven Andrés
9327c9b58b added whitelist check 2020-05-05 14:18:52 -07:00
Steven Andrés
5644001c53 added "whitelist" under [traffic] 2020-05-05 14:17:15 -07:00
Steven Andrés
91f78ecd0f added "whitelist" under [traffic] 2020-05-05 14:16:22 -07:00
143 changed files with 11220 additions and 8559 deletions

14
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
# src: https://github.com/marketplace/actions/build-and-push-docker-images#keep-up-to-date-with-github-dependabot
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
# Also keep PHP (Composer) dependencies up-to-date
# see: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"

View File

@@ -33,11 +33,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -46,4 +46,4 @@ jobs:
# queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

View File

@@ -2,9 +2,9 @@ name: Refresh PHP 8 branch
on:
push:
branches: [ master ]
branches: [ master ]
schedule:
- cron: '42 2 * * *'
- cron: '42 2 * * *'
workflow_dispatch:
jobs:
@@ -12,8 +12,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout php8 branch
uses: actions/checkout@v2
- name: Checkout php8 branch
uses: actions/checkout@v3
with:
# directly checkout the php8 branch
ref: php8
@@ -28,7 +28,7 @@ jobs:
git merge origin/master
- name: Push new changes
uses: github-actions-x/commit@v2.8
uses: github-actions-x/commit@v2.9
with:
name: github-actions[bot]
email: 41898282+github-actions[bot]@users.noreply.github.com

View File

@@ -13,7 +13,7 @@ jobs:
snyk-php:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v3
- name: Install Google Cloud Storage
run: composer require --no-update google/cloud-storage && composer update --no-dev
- name: Run Snyk to check for vulnerabilities
@@ -24,6 +24,6 @@ jobs:
with:
args: --sarif-file-output=snyk.sarif
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v1
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: snyk.sarif

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Validate composer.json and composer.lock
run: composer validate
- name: Install dependencies
@@ -27,7 +27,7 @@ jobs:
# let's get started!
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
# cache PHP extensions
- name: Setup cache environment
@@ -39,7 +39,7 @@ jobs:
key: ${{ runner.os }}-${{ env.extensions-cache-key }}
- name: Cache extensions
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ steps.extcache.outputs.dir }}
key: ${{ steps.extcache.outputs.key }}
@@ -65,18 +65,17 @@ jobs:
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
# http://man7.org/linux/man-pages/man1/date.1.html
# https://github.com/actions/cache#creating-a-cache-key
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
run: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
shell: bash
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/composer.json') }}
@@ -99,23 +98,23 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: '12'
node-version: '16'
cache: 'npm'
cache-dependency-path: 'js/package.json'
cache-dependency-path: 'js/package-lock.json'
- name: Setup Mocha
run: npm install -g mocha
- name: Setup Node modules
run: npm install
run: npm ci
working-directory: js
- name: Run unit tests
run: mocha
run: npm test
working-directory: js

View File

@@ -1,18 +1,32 @@
# PrivateBin version history
* **1.4 (not yet released)**
* ADDED: Translations for Estonian and Lojban
* **1.4.1 (not yet released)**
* ADDED: Translations for Turkish, Slovak and Greek
* ADDED: S3 Storage backend (#994)
* ADDED: Jdenticons as an option for comment icons (#793)
* CHANGED: Avoid `SUPER` privilege for setting the `sql_mode` for MariaDB/MySQL (#919)
* CHANGED: Upgrading libraries to: zlib 1.2.13
* FIXED: Revert to CREATE INDEX without IF NOT EXISTS clauses, to support MySQL (#943)
* FIXED: Apply table prefix to indexes as well, to support multiple instances sharing a single database (#943)
* FIXED: YOURLS integration via new proxy, storing signature in configuration (#725)
* **1.4 (2022-04-09)**
* ADDED: Translations for Corsican, Estonian, Finnish and Lojban
* ADDED: new HTTP headers improving security (#765)
* ADDED: Download button for paste text (#774)
* ADDED: Opt-out of federated learning of cohorts (FLoC) (#776)
* ADDED: Configuration option to exempt IPs from the rate-limiter (#787)
* ADDED: Google Cloud Storage backend support (#795)
* ADDED: Oracle database support (#868)
* ADDED: Configuration option to limit paste creation and commenting to certain IPs (#883)
* ADDED: Set CSP also as meta tag, to deal with misconfigured webservers mangling the HTTP header
* ADDED: Sanitize SVG preview, preventing script execution in instance context
* CHANGED: Language selection cookie only transmitted over HTTPS (#472)
* CHANGED: Upgrading libraries to: base-x 4.0.0, DOMpurify 2.3.6, ip-lib 1.18.0, jQuery 3.6.0, random_compat 2.0.21 & Showdown 2.0.0
* CHANGED: Upgrading libraries to: base-x 4.0.0, bootstrap 3.4.1 (JS), DOMpurify 2.3.6, ip-lib 1.18.0, jQuery 3.6.0, random_compat 2.0.21, Showdown 2.0.3 & zlib 1.2.12
* CHANGED: Removed automatic `.ini` configuration file migration (#808)
* CHANGED: Removed configurable `dir` for `traffic` & `purge` limiters (#419)
* CHANGED: Server salt, traffic and purge limiter now stored in the storage backend (#419)
* CHANGED: Drop support for attachment download in IE
* FIXED: Error when attachments are disabled, but paste with attachment gets displayed
* **1.3.5 (2021-04-05)**
* ADDED: Translations for Hebrew, Lithuanian, Indonesian and Catalan
* ADDED: Make the project info configurable (#681)
@@ -55,7 +69,7 @@
* FIXED: HTML injection via unescaped attachment filename (#554)
* FIXED: Password disabling option (#527)
* **1.2.2 (2020-01-11)**
* CHANGED: Upgrading libraries to: bootstrap 3.4.1, DOMpurify 2.0.7, jQuery 3.4.1, kjua 0.6.0, Showdown 1.9.1 & SJCL 1.0.8
* CHANGED: Upgrading libraries to: bootstrap 3.4.1 (CSS), DOMpurify 2.0.7, jQuery 3.4.1, kjua 0.6.0, Showdown 1.9.1 & SJCL 1.0.8
* FIXED: HTML injection via unescaped attachment filename (#554)
* **1.3.1 (2019-09-22)**
* ADDED: Translation for Bulgarian (#455)

View File

@@ -2,18 +2,17 @@
## Active contributors
Simon Rupf - current developer and maintainer
rugk - security review, doc improvment, JS refactoring & various other stuff
R4SAS - python client, compression, blob URI to support larger attachments
* Simon Rupf - current developer and maintainer
* rugk - security review, doc improvment, JS refactoring & various other stuff
* R4SAS - python client, compression, blob URI to support larger attachments
## Past contributions
Sébastien Sauvage - original idea and main developer
* Sébastien Sauvage - original idea and main developer
* Alexey Gladkov - syntax highlighting
* Greg Knaddison - robots.txt
* MrKooky - HTML5 markup, CSS cleanup
* Simon Rupf - WebCrypto, unit tests, containers images, database backend, MVC, configuration, i18n
* Simon Rupf - WebCrypto, unit tests, container images, database backend, MVC, configuration, i18n
* Hexalyse - Password protection
* Viktor Stanchev - File upload support
* azlux - Tab character input support
@@ -30,6 +29,8 @@ Sébastien Sauvage - original idea and main developer
* rodehoed - option to exempt ips from the rate-limiter
* Mark van Holsteijn - Google Cloud Storage backend
* Austin Huang - Oracle database support
* Felix J. Ogris - S3 Storage backend
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
## Translations
* Hexalyse - French
@@ -55,3 +56,8 @@ Sébastien Sauvage - original idea and main developer
* retiolus - Catalan
* sarnane - Estonian
* foxsouns - Lojban
* Patriccollu di Santa Maria è Sichè - Corsican
* Markus Mikkonen - Finnish
* Emir Ensar Rahmanlar - Turkish
* Stevo984 - Slovak
* Christos Karamolegkos - Greek

View File

@@ -1,39 +1,47 @@
# Installation
**TL;DR:** Download the
[latest release archive](https://github.com/PrivateBin/PrivateBin/releases/latest) (with the link labelled as „Source code (…)“)
and extract it in your web hosts folder where you want to install your PrivateBin
instance. We try to provide a mostly safe default configuration, but we urge you to
check the [security section](#hardening-and-security) below and the [configuration
options](#configuration) to adjust as you see fit.
[latest release archive](https://github.com/PrivateBin/PrivateBin/releases/latest)
(with the link labelled as "Source code (…)") and extract it in your web hosts
folder where you want to install your PrivateBin instance. We try to provide a
mostly safe default configuration, but we urge you to check the
[security section](#hardening-and-security) below and the
[configuration options](#configuration) to adjust as you see fit.
**NOTE:** See [our FAQ](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#how-can-i-securely-clonedownload-your-project) for information how to securely download the PrivateBin release files.
**NOTE:** See our [FAQ entry on securely downloading release files](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#how-can-i-securely-clonedownload-your-project)
for more information.
**NOTE:** There is a [ansible](https://ansible.com) role by @e1mo available to install and configure PrivateBin on your server. It's available on [ansible galaxy](https://galaxy.ansible.com/e1mo/privatebin) ([source code](https://git.sr.ht/~e1mo/ansible-role-privatebin)).
**NOTE:** There is a [ansible](https://ansible.com) role by @e1mo available to
install and configure PrivateBin on your server. It's available on
[ansible galaxy](https://galaxy.ansible.com/e1mo/privatebin)
([source code](https://git.sr.ht/~e1mo/ansible-role-privatebin)).
### Minimal requirements
### Minimal Requirements
- PHP version 7.0 or above
- Or PHP version 5.6 AND _one_ of the following sources of cryptographically safe randomness:
- [Libsodium](https://download.libsodium.org/libsodium/content/installation/) and it's [PHP extension](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium)
- open_basedir access to `/dev/urandom`
- mcrypt extension (mcrypt needs to be able to access `/dev/urandom`. This means if `open_basedir` is set, it must include this file.)
- Or PHP version 5.6 AND _one_ of the following sources of cryptographically
safe randomness:
- [Libsodium](https://download.libsodium.org/libsodium/content/installation/)
and it's [PHP extension](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium)
- `open_basedir` access to `/dev/urandom`
- mcrypt extension AND `open_basedir` access to `/dev/urandom`
- com_dotnet extension
- GD extension
- GD extension (when using identicon or vizhash icons, jdenticon works without it)
- zlib extension
- some disk space or (optionally) a database supported by [PDO](https://php.net/manual/book.pdo.php)
- ability to create files and folders in the installation directory and the PATH defined in index.php
- A web browser with JavaScript support
- some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php)
- ability to create files and folders in the installation directory and the PATH
defined in index.php
- A web browser with JavaScript and (optional) WebAssembly support
## Hardening and security
## Hardening and Security
### Changing the path
### Changing the Path
In the index.php you can define a different `PATH`. This is useful to secure your
installation. You can move the configuration, data files, templates and PHP
In the index.php you can define a different `PATH`. This is useful to secure
your installation. You can move the configuration, data files, templates and PHP
libraries (directories cfg, doc, data, lib, tpl, tst and vendor) outside of your
document root. This new location must still be accessible to your webserver / PHP
process (see also
document root. This new location must still be accessible to your webserver and
PHP process (see also
[open_basedir setting](https://secure.php.net/manual/en/ini.core.php#ini.open-basedir)).
> #### PATH Example
@@ -42,24 +50,25 @@ process (see also
> http://example.com/paste/
>
> The full path of PrivateBin on your webserver is:
> /home/example.com/htdocs/paste
> /srv/example.com/htdocs/paste
>
> When setting the path like this:
> define('PATH', '../../secret/privatebin/');
>
> PrivateBin will look for your includes / data here:
> /home/example.com/secret/privatebin
> PrivateBin will look for your includes and data here:
> /srv/example.com/secret/privatebin
### Changing the config path only
In situations where you want to keep the PrivateBin static files separate from the
rest of your data, or you want to reuse the installation files on multiple vhosts,
you may only want to change the `conf.php`. In this instance, you can set the
you may only want to change the `conf.php`. In this case, you can set the
`CONFIG_PATH` environment variable to the absolute path to the `conf.php` file.
This can be done in your web server's virtual host config, the PHP config, or in
the index.php if you choose to customize it.
the index.php, if you choose to customize it.
Note that your PHP process will need read access to the config wherever it may be.
Note that your PHP process will need read access to the configuration file,
wherever it may be.
> #### CONFIG_PATH example
> Setting the value in an Apache Vhost:
@@ -73,23 +82,27 @@ Note that your PHP process will need read access to the config wherever it may b
### Transport security
When setting up PrivateBin, also set up HTTPS, if you haven't already. Without HTTPS
PrivateBin is not secure, as the JavaScript files could be manipulated during transmission.
For more information on this, see our [FAQ entry on HTTPS setup](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#how-should-i-setup-https).
When setting up PrivateBin, also set up HTTPS, if you haven't already. Without
HTTPS PrivateBin is not secure, as the JavaScript or WebAssembly files could be
manipulated during transmission. For more information on this, see our
[FAQ entry on HTTPS setup recommendations](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#how-should-i-setup-https).
### File-level permissions
After completing the installation, you should make sure, other users on the system cannot read the config file or the `data/` directory, as depending on your configuration potential secret information are saved there.
After completing the installation, you should make sure, that other users on the
system cannot read the config file or the `data/` directory, as depending on
your configuration potentially sensitive information may be stored in there.
See [this FAQ item](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#what-are-the-recommended-file-and-folder-permissions-for-privatebin) for a detailed guide on how to "harden" the permissions of files and folders.
See our [FAQ entry on permissions](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#what-are-the-recommended-file-and-folder-permissions-for-privatebin)
for a detailed guide on how to "harden" access to files and folders.
## Configuration
In the file `cfg/conf.php` you can configure PrivateBin. A `cfg/conf.sample.php`
is provided containing all options and default values. You can copy it to
`cfg/conf.php` and adapt it as needed. Alternatively you can copy it anywhere and
set the `CONFIG_PATH` environment variable (see above notes). The config file is
divided into multiple sections, which are enclosed in square brackets.
is provided containing all options and their default values. You can copy it to
`cfg/conf.php` and change it as needed. Alternatively you can copy it anywhere
and set the `CONFIG_PATH` environment variable (see above notes). The config
file is divided into multiple sections, which are enclosed in square brackets.
In the `[main]` section you can enable or disable the discussion feature, set
the limit of stored pastes and comments in bytes. The `[traffic]` section lets
@@ -107,28 +120,28 @@ A `robots.txt` file is provided in the root dir of PrivateBin. It disallows all
robots from accessing your pastes. It is recommend to place it into the root of
your web directory if you have installed PrivateBin in a subdirectory. Make sure
to adjust it, so that the file paths match your installation. Of course also
adjust the file if you already use a `robots.txt`.
adjust the file, if you already use a `robots.txt`.
A `.htaccess.disabled` file is provided in the root dir of PrivateBin. It blocks
some known robots and link-scanning bots. If you use Apache, you can rename the
file to `.htaccess` to enable this feature. If you use another webserver, you
have to configure it manually to do the same.
### When using Cloudflare
### On using Cloudflare
If you want to use PrivateBin behind Cloudflare, make sure you have disabled the Rocket
loader and unchecked "Javascript" for Auto Minify, found in your domain settings,
under "Speed". (More information
[in this FAQ entry](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#user-content-how-to-make-privatebin-work-when-using-cloudflare-for-ddos-protection))
If you want to use PrivateBin behind Cloudflare, make sure you have disabled the
Rocket loader and unchecked "Javascript" for Auto Minify, found in your domain
settings, under "Speed". More information can be found in our
[FAQ entry on Cloudflare related issues](https://github.com/PrivateBin/PrivateBin/wiki/FAQ#user-content-how-to-make-privatebin-work-when-using-cloudflare-for-ddos-protection).
### Using a database instead of flat files
### Using a Database Instead of Flat Files
In the configuration file the `[model]` and `[model_options]` sections let you
configure your favourite way of storing the pastes and discussions on your
server.
`Filesystem` is the default model, which stores everything in files in the
data folder. This is the recommended setup for most sites.
data folder. This is the recommended setup for most sites on single hosts.
Under high load, in distributed setups or if you are not allowed to store files
locally, you might want to switch to the `Database` model. This lets you
@@ -142,21 +155,26 @@ to use a prefix for
The table prefix option is called `tbl`.
> #### Note
> The `Database` model has only been tested with SQLite, MySQL and PostgreSQL,
> although it would not be recommended to use SQLite in a production environment.
> If you gain any experience running PrivateBin on other RDBMS, please let us
> know.
> The `Database` model has only been tested with SQLite, MariaDB/MySQL and
> PostgreSQL, although it would not be recommended to use SQLite in a production
> environment. If you gain any experience running PrivateBin on other RDBMS,
> please let us know.
The following GRANTs (privileges) are required for the PrivateBin user in **MySQL**. In normal operation:
The following GRANTs (privileges) are required for the PrivateBin user in
**MariaDB/MySQL**. In normal operation:
- INSERT, SELECT, DELETE on the paste and comment tables
- SELECT on the config table
If you want PrivateBin to handle table creation (when you create the first paste) and updates (after you update PrivateBin to a new release), you need to give the user these additional privileges:
If you want PrivateBin to handle table creation (when you create the first paste)
and updates (after you update PrivateBin to a new release), you need to give the
user these additional privileges:
- CREATE, INDEX and ALTER on the database
- INSERT and UPDATE on the config table
For reference or if you want to create the table schema for yourself to avoid having to give PrivateBin too many permissions (replace
`prefix_` with your own table prefix and create the table schema with your favourite MySQL console):
For reference or if you want to create the table schema for yourself to avoid
having to give PrivateBin too many permissions (replace `prefix_` with your own
table prefix and create the table schema with your favourite MariaDB/MySQL
client):
```sql
CREATE TABLE prefix_paste (
@@ -187,7 +205,7 @@ CREATE INDEX parent ON prefix_comment(pasteid);
CREATE TABLE prefix_config (
id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id)
);
INSERT INTO prefix_config VALUES('VERSION', '1.3.5');
INSERT INTO prefix_config VALUES('VERSION', '1.4.0');
```
In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns
@@ -199,11 +217,11 @@ to be `CLOB` and not `BLOB` or `MEDIUMBLOB`, the `id` column in the `config`
table needs to be `VARCHAR2(16)` and the `meta` column in the `paste` table
and the `value` column in the `config` table need to be `VARCHAR2(4000)`.
### Using Google Cloud Storage
#### Using Google Cloud Storage
If you want to deploy PrivateBin in a serverless manner in the Google Cloud, you
can choose the `GoogleCloudStorage` as backend. To use this backend, you create
a GCS bucket and specify the name as the model option `bucket`. Alternatively,
you can set the name through the environment variable PASTEBIN_GCS_BUCKET.
you can set the name through the environment variable `PRIVATEBIN_GCS_BUCKET`.
The default prefix for pastes stored in the bucket is `pastes`. To change the
prefix, specify the option `prefix`.
@@ -214,3 +232,42 @@ Platform using Google Cloud Run is easy and cheap.
To use the Google Cloud Storage backend you have to install the suggested
library using the command `composer require google/cloud-storage`.
#### Using S3 Storage
Similar to Google Cloud Storage, you can choose S3 as storage backend. It uses
the AWS SDK for PHP, but can also talk to a Rados gateway as part of a CEPH
cluster. To use this backend, you first have to install the SDK in the
document root of PrivateBin: `composer require aws/aws-sdk-php`. You have to
create the S3 bucket on the CEPH cluster before using the S3 backend.
In the `[model]` section of cfg/conf.php, set `class` to `S3Storage`.
You can set any combination of the following options in the `[model_options]`
section:
* region
* version
* endpoint
* bucket
* prefix
* accesskey
* secretkey
* use_path_style_endpoint
By default, prefix is empty. If set, the S3 backend will place all PrivateBin
data beneath this prefix.
For AWS, you have to provide at least `region`, `bucket`, `accesskey`, and
`secretkey`.
For CEPH, follow this example:
```
region = ""
version = "2006-03-01"
endpoint = "https://s3.my-ceph.invalid"
use_path_style_endpoint = true
bucket = "my-bucket"
accesskey = "my-rados-user"
secretkey = "my-rados-pass"
```

View File

@@ -1,7 +1,7 @@
.PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
CURRENT_VERSION = 1.3.5
VERSION ?= 1.3.6
CURRENT_VERSION = 1.4.0
VERSION ?= 1.4.1
VERSION_FILES = index.php cfg/ *.md css/ i18n/ img/ js/package.json js/privatebin.js lib/ Makefile tpl/ tst/
REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")
@@ -33,12 +33,13 @@ increment: ## Increment and commit new version number, set target version using
do \
sed -i "s/$(REGEX_CURRENT_VERSION)/$(REGEX_VERSION)/g" $$F; \
done
git add $(VERSION_FILES)
cd tst && phpunit --no-coverage && cd ..
git add $(VERSION_FILES) tpl/
git commit -m "incrementing version"
sign: ## Sign a release.
git tag $(VERSION)
git push --tags
git push origin $(VERSION)
signrelease.sh
test: test-js test-php ## Run all unit tests.

View File

@@ -1,25 +1,27 @@
# [![PrivateBin](https://cdn.rawgit.com/PrivateBin/assets/master/images/preview/logoSmall.png)](https://privatebin.info/)
*Current version: 1.3.5*
*Current version: 1.4.0*
**PrivateBin** is a minimalist, open source online [pastebin](https://en.wikipedia.org/wiki/Pastebin)
**PrivateBin** is a minimalist, open source online
[pastebin](https://en.wikipedia.org/wiki/Pastebin)
where the server has zero knowledge of pasted data.
Data is encrypted and decrypted in the browser using 256bit AES in [Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
Data is encrypted and decrypted in the browser using 256bit AES in
[Galois Counter mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode).
This is a fork of ZeroBin, originally developed by
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). ZeroBin was refactored
to allow easier and cleaner extensions. PrivateBin has many more features than the
original ZeroBin. It is, however, still fully compatible to the original ZeroBin 0.19
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). PrivateBin was
refactored to allow easier and cleaner extensions and has many additional
features. It is, however, still fully compatible to the original ZeroBin 0.19
data storage scheme. Therefore, such installations can be upgraded to PrivateBin
without losing any data.
## What PrivateBin provides
+ As a server administrator you don't have to worry if your users post content
that is considered illegal in your country. You have no knowledge of any
of the pastes content. If requested or enforced, you can delete any paste from
your system.
that is considered illegal in your country. You have plausible deniability of
any of the pastes content. If requested or enforced, you can delete any paste
from your system.
+ Pastebin-like system to store text documents, code samples, etc.
@@ -31,13 +33,13 @@ without losing any data.
## What it doesn't provide
- As a user you have to trust the server administrator not to inject any malicious
javascript code.
For basic security, the PrivateBin installation *has to provide HTTPS*!
Otherwise you would also have to trust your internet provider, and any country
the traffic passes through.
Additionally the instance should be secured by
[HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security). It can use traditional certificate authorities and/or use
- As a user you have to trust the server administrator not to inject any
malicious code. For security, a PrivateBin installation *has to be used over*
*HTTPS*! Otherwise you would also have to trust your internet provider, and
any jurisdiction the traffic passes through. Additionally the instance should
be secured by
[HSTS](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security). It can
use traditional certificate authorities and/or use a
[DNSSEC](https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions)
protected
[DANE](https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities)
@@ -45,18 +47,17 @@ without losing any data.
- The "key" used to encrypt the paste is part of the URL. If you publicly post
the URL of a paste that is not password-protected, anyone can read it.
Use a password if you want your paste to be private. In this case, make sure to
use a strong password and only share it privately and end-to-end-encrypted.
Use a password if you want your paste to remain private. In that case, make
sure to use a strong password and share it privately and end-to-end-encrypted.
- A server admin might be forced to hand over access logs to the authorities.
- A server admin can be forced to hand over access logs to the authorities.
PrivateBin encrypts your text and the discussion contents, but who accessed a
paste (first) might still be disclosed via access logs.
- In case of a server breach your data is secure as it is only stored encrypted
on the server. However, the server could be misused or the server admin could
be legally forced into sending malicious JavaScript to all web users, which
grabs the decryption key and sends it to the server when a user accesses a
PrivateBin.
on the server. However, the server could be absused or the server admin could
be legally forced into sending malicious code to their users, which logs
the decryption key and sends it to a server when a user accesses a paste.
Therefore, do not access any PrivateBin instance if you think it has been
compromised. As long as no user accesses this instance with a previously
generated URL, the content can't be decrypted.
@@ -77,8 +78,8 @@ file](https://github.com/PrivateBin/PrivateBin/wiki/Configuration):
* Syntax highlighting for source code using prettify.js, including 4 prettify
themes
* File upload support, images get displayed (disabled by default, possibility
to adjust size limit)
* File upload support, image, media and PDF preview (disabled by default, size
limit adjustable)
* Templates: By default there are bootstrap CSS, darkstrap and "classic ZeroBin"
to choose from and it is easy to adapt these to your own websites layout or
@@ -89,7 +90,7 @@ file](https://github.com/PrivateBin/PrivateBin/wiki/Configuration):
* Language selection (disabled by default, as it uses a session cookie)
* QR code generation of URL, to easily transfer pastes over to a mobile device
* QR code for paste URLs, to easily transfer them over to mobile devices
## Further resources

View File

@@ -4,8 +4,8 @@
| Version | Supported |
| ------- | ------------------ |
| 1.3.5 | :heavy_check_mark: |
| < 1.3.5 | :x: |
| 1.4.0 | :heavy_check_mark: |
| < 1.4.0 | :x: |
## Reporting a Vulnerability

View File

@@ -65,10 +65,11 @@ languageselection = false
; qrcode = true
; (optional) IP based icons are a weak mechanism to detect if a comment was from
; a different user when the same username was used in a comment. It might be
; used to get the IP of a non anonymous comment poster if the server salt is
; leaked and a SHA256 HMAC rainbow table is generated for all (relevant) IPs.
; Can be set to one these values: "none" / "vizhash" / "identicon" (default).
; a different user when the same username was used in a comment. It might get
; used to get the IP of a comment poster if the server salt is leaked and a
; SHA512 HMAC rainbow table is generated for all (relevant) IPs.
; Can be set to one these values:
; "none" / "identicon" (default) / "jdenticon" / "vizhash".
; icon = "none"
; Content Security Policy headers allow a website to restrict what sources are
@@ -87,7 +88,7 @@ languageselection = false
; async functions and display an error if not and for Chrome to enable
; webassembly support (used for zlib compression). You can remove it if Chrome
; doesn't need to be supported and old browsers don't need to be warned.
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval' resource:; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
; stay compatible with PrivateBin Alpha 0.19, less secure
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
@@ -135,9 +136,17 @@ markdown = "Markdown"
; Set this to 0 to disable rate limiting.
limit = 10
; Set ips (v4|v6) which should be exempted for the rate-limit. CIDR also supported. Needed to be comma separated.
; Unset for enabling and invalid values will be ignored
; eg: exemptedIp = '1.2.3.4,10.10.10/24'
; (optional) Set IPs addresses (v4 or v6) or subnets (CIDR) which are exempted
; from the rate-limit. Invalid IPs will be ignored. If multiple values are to
; be exempted, the list needs to be comma separated. Leave unset to disable
; exemptions.
; exempted = "1.2.3.4,10.10.10/24"
; (optional) If you want only some source IP addresses (v4 or v6) or subnets
; (CIDR) to be allowed to create pastes, set these here. Invalid IPs will be
; ignored. If multiple values are to be exempted, the list needs to be comma
; separated. Leave unset to allow anyone to create pastes.
; creators = "1.2.3.4,10.10.10/24"
; (optional) if your website runs behind a reverse proxy or load balancer,
; set the HTTP header containing the visitors IP address, i.e. X_FORWARDED_FOR
@@ -167,6 +176,7 @@ dir = PATH "data"
;[model_options]
;bucket = "my-private-bin"
;prefix = "pastes"
;uniformacl = false
;[model]
; example of DB configuration for MySQL
@@ -186,3 +196,52 @@ dir = PATH "data"
;usr = null
;pwd = null
;opt[12] = true ; PDO::ATTR_PERSISTENT
;[model]
; example of DB configuration for PostgreSQL
;class = Database
;[model_options]
;dsn = "pgsql:host=localhost;dbname=privatebin"
;tbl = "privatebin_" ; table prefix
;usr = "privatebin"
;pwd = "Z3r0P4ss"
;opt[12] = true ; PDO::ATTR_PERSISTENT
;[model]
; example of S3 configuration for Rados gateway / CEPH
;class = S3Storage
;[model_options]
;region = ""
;version = "2006-03-01"
;endpoint = "https://s3.my-ceph.invalid"
;use_path_style_endpoint = true
;bucket = "my-bucket"
;accesskey = "my-rados-user"
;secretkey = "my-rados-pass"
;[model]
; example of S3 configuration for AWS
;class = S3Storage
;[model_options]
;region = "eu-central-1"
;version = "latest"
;bucket = "my-bucket"
;accesskey = "access key id"
;secretkey = "secret access key"
[yourls]
; don't mix this up with "urlshortener" config item:
; - when using a standard configuration, "urlshortener" will point to the YOURLS
; API, including access credentials, and will be part of the PrivateBin public
; web page (insecure!)
; - when using the parameters in this section ("signature" and "apiurl"),
; "urlshortener" will point to a fixed PrivateBin page
; ("$basepath/shortenviayourls?link=") and that URL will in turn call YOURLS
; server-side, using the URL from "apiurl" and the "access signature" from the
; "signature" parameters below.
; (optional) the "signature" (access key) issued by YOURLS for the using account
; signature = ""
; (optional) the URL of the YOURLS API, called to shorten a PrivateBin URL
; apiurl = ""

View File

@@ -27,10 +27,12 @@
"php" : "^5.6.0 || ^7.0 || ^8.0",
"paragonie/random_compat" : "2.0.21",
"yzalis/identicon" : "2.0.0",
"mlocati/ip-lib" : "1.18.0"
"mlocati/ip-lib" : "1.18.0",
"jdenticon/jdenticon": "^1.0"
},
"suggest" : {
"google/cloud-storage" : "1.26.1"
"google/cloud-storage" : "1.26.1",
"aws/aws-sdk-php" : "3.239.0"
},
"require-dev" : {
"phpunit/phpunit" : "^4.6 || ^5.0"

469
composer.lock generated
View File

@@ -4,8 +4,57 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "fa52d4988bfe17d4b27e3a4789a1ec49",
"content-hash": "17bceced29627163f7aa330a0697f68b",
"packages": [
{
"name": "jdenticon/jdenticon",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/dmester/jdenticon-php.git",
"reference": "994ee07293fb978f983393ffcb2c0250592a6ac4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dmester/jdenticon-php/zipball/994ee07293fb978f983393ffcb2c0250592a6ac4",
"reference": "994ee07293fb978f983393ffcb2c0250592a6ac4",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Jdenticon\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Mester Pirttijärvi"
}
],
"description": "Render PNG and SVG identicons.",
"homepage": "https://jdenticon.com/",
"keywords": [
"avatar",
"identicon",
"jdenticon"
],
"support": {
"docs": "https://jdenticon.com/php-api.html",
"issues": "https://github.com/dmester/jdenticon-php/issues",
"source": "https://github.com/dmester/jdenticon-php"
},
"time": "2022-07-02T11:03:15+00:00"
},
{
"name": "mlocati/ip-lib",
"version": "1.18.0",
@@ -61,6 +110,10 @@
"range",
"subnet"
],
"support": {
"issues": "https://github.com/mlocati/ip-lib/issues",
"source": "https://github.com/mlocati/ip-lib/tree/1.18.0"
},
"funding": [
{
"url": "https://github.com/sponsors/mlocati",
@@ -120,6 +173,11 @@
"pseudorandom",
"random"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/random_compat/issues",
"source": "https://github.com/paragonie/random_compat"
},
"time": "2022-02-16T17:07:03+00:00"
},
{
@@ -172,6 +230,10 @@
"identicon",
"image"
],
"support": {
"issues": "https://github.com/yzalis/Identicon/issues",
"source": "https://github.com/yzalis/Identicon/tree/master"
},
"abandoned": true,
"time": "2019-10-14T09:30:57+00:00"
}
@@ -179,31 +241,34 @@
"packages-dev": [
{
"name": "doctrine/instantiator",
"version": "1.4.0",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
"php": ">=5.3,<8.0-DEV"
},
"require-dev": {
"doctrine/coding-standard": "^8.0",
"athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
@@ -217,55 +282,42 @@
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "https://ocramius.github.io/"
"homepage": "http://ocramius.github.com/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"constructor",
"instantiate"
],
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
"type": "tidelift"
}
],
"time": "2020-11-10T18:47:58+00:00"
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/master"
},
"time": "2015-06-14T21:17:01+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.10.2",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
"reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"replace": {
"myclabs/deep-copy": "self.version"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"doctrine/collections": "^1.0",
"doctrine/common": "^2.6",
"phpunit/phpunit": "^7.1"
"phpunit/phpunit": "^4.1"
},
"type": "library",
"autoload": {
@@ -288,40 +340,43 @@
"object",
"object graph"
],
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2020-11-13T09:40:50+00:00"
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.x"
},
"time": "2017-10-19T19:58:43+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
"reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
"reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^4.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.x-dev"
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src/"
"phpDocumentor\\Reflection\\": [
"src"
]
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -343,42 +398,42 @@
"reflection",
"static analysis"
],
"time": "2020-06-27T09:03:43+00:00"
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
},
"time": "2017-09-11T18:02:19+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.3.0",
"version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
"reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2",
"reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2",
"shasum": ""
},
"require": {
"ext-filter": "*",
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.2",
"phpdocumentor/type-resolver": "^1.3",
"webmozart/assert": "^1.9.1"
"php": "^5.6 || ^7.0",
"phpdocumentor/reflection-common": "^1.0.0",
"phpdocumentor/type-resolver": "^0.4.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
"mockery/mockery": "~1.3.2",
"psalm/phar": "^4.8"
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -389,46 +444,48 @@
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
},
{
"name": "Jaap van Otterdijk",
"email": "account@ijaap.nl"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2021-10-19T17:43:47+00:00"
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/3.x"
},
"time": "2017-11-10T14:09:06+00:00"
},
{
"name": "phpdocumentor/type-resolver",
"version": "1.6.0",
"version": "0.4.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
"reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
"reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0"
"php": "^5.5 || ^7.0",
"phpdocumentor/reflection-common": "^1.0"
},
"require-dev": {
"ext-tokenizer": "*",
"psalm/phar": "^4.8"
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^5.2||^4.8.24"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-1.x": "1.x-dev"
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": "src"
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -441,8 +498,11 @@
"email": "me@mikevanriel.com"
}
],
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"time": "2022-01-04T19:58:01+00:00"
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
},
"time": "2017-07-14T14:27:02+00:00"
},
{
"name": "phpspec/prophecy",
@@ -505,6 +565,10 @@
"spy",
"stub"
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
},
"time": "2020-03-05T15:02:03+00:00"
},
{
@@ -568,6 +632,11 @@
"testing",
"xunit"
],
"support": {
"irc": "irc://irc.freenode.net/phpunit",
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/4.0"
},
"time": "2017-04-02T07:44:40+00:00"
},
{
@@ -615,6 +684,11 @@
"filesystem",
"iterator"
],
"support": {
"irc": "irc://irc.freenode.net/phpunit",
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5"
},
"time": "2017-11-27T13:52:08+00:00"
},
{
@@ -656,6 +730,10 @@
"keywords": [
"template"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
"source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
},
"time": "2015-06-21T13:50:34+00:00"
},
{
@@ -705,33 +783,37 @@
"keywords": [
"timer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
"source": "https://github.com/sebastianbergmann/php-timer/tree/master"
},
"time": "2017-02-26T11:10:40+00:00"
},
{
"name": "phpunit/php-token-stream",
"version": "2.0.2",
"version": "1.4.12",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "791198a2c6254db10131eecfe8c06670700904db"
"reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
"reference": "791198a2c6254db10131eecfe8c06670700904db",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16",
"reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": "^7.0"
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "^6.2.4"
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "1.4-dev"
}
},
"autoload": {
@@ -754,21 +836,25 @@
"keywords": [
"tokenizer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4"
},
"abandoned": true,
"time": "2017-11-27T05:48:46+00:00"
"time": "2017-12-04T08:55:13+00:00"
},
{
"name": "phpunit/phpunit",
"version": "5.7.27",
"version": "5.6.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c"
"reference": "a9de0dbafeb6b1391b391fbb034734cb0af9f67c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
"reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a9de0dbafeb6b1391b391fbb034734cb0af9f67c",
"reference": "a9de0dbafeb6b1391b391fbb034734cb0af9f67c",
"shasum": ""
},
"require": {
@@ -779,21 +865,21 @@
"ext-xml": "*",
"myclabs/deep-copy": "~1.3",
"php": "^5.6 || ^7.0",
"phpspec/prophecy": "^1.6.2",
"phpunit/php-code-coverage": "^4.0.4",
"phpspec/prophecy": "^1.3.1",
"phpunit/php-code-coverage": "^4.0.1",
"phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "^3.2",
"sebastian/comparator": "^1.2.4",
"sebastian/diff": "^1.4.3",
"sebastian/environment": "^1.3.4 || ^2.0",
"sebastian/exporter": "~2.0",
"sebastian/global-state": "^1.1",
"sebastian/object-enumerator": "~2.0",
"sebastian/comparator": "~1.1",
"sebastian/diff": "~1.2",
"sebastian/environment": "^1.3 || ^2.0",
"sebastian/exporter": "~1.2",
"sebastian/global-state": "~1.0",
"sebastian/object-enumerator": "~1.0",
"sebastian/resource-operations": "~1.0",
"sebastian/version": "^1.0.6|^2.0.1",
"symfony/yaml": "~2.1|~3.0|~4.0"
"sebastian/version": "~1.0|~2.0",
"symfony/yaml": "~2.1|~3.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "3.0.2"
@@ -811,7 +897,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.7.x-dev"
"dev-master": "5.6.x-dev"
}
},
"autoload": {
@@ -837,7 +923,11 @@
"testing",
"xunit"
],
"time": "2018-02-01T05:50:59+00:00"
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/5.6.3"
},
"time": "2016-11-14T06:39:40+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -896,6 +986,11 @@
"mock",
"xunit"
],
"support": {
"irc": "irc://irc.freenode.net/phpunit",
"issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
"source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.4"
},
"abandoned": true,
"time": "2017-06-30T09:13:00+00:00"
},
@@ -942,6 +1037,10 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"support": {
"issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
"source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@@ -1012,6 +1111,10 @@
"compare",
"equality"
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/1.2"
},
"time": "2017-01-29T09:50:25+00:00"
},
{
@@ -1064,6 +1167,10 @@
"keywords": [
"diff"
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/1.4"
},
"time": "2017-05-22T07:24:03+00:00"
},
{
@@ -1114,25 +1221,29 @@
"environment",
"hhvm"
],
"support": {
"issues": "https://github.com/sebastianbergmann/environment/issues",
"source": "https://github.com/sebastianbergmann/environment/tree/master"
},
"time": "2016-11-26T07:53:53+00:00"
},
{
"name": "sebastian/exporter",
"version": "2.0.0",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
"reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/recursion-context": "~2.0"
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"ext-mbstring": "*",
@@ -1141,7 +1252,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -1181,7 +1292,11 @@
"export",
"exporter"
],
"time": "2016-11-19T08:54:04+00:00"
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/master"
},
"time": "2016-06-17T09:04:28+00:00"
},
{
"name": "sebastian/global-state",
@@ -1232,25 +1347,29 @@
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1"
},
"time": "2015-10-12T03:26:01+00:00"
},
{
"name": "sebastian/object-enumerator",
"version": "2.0.1",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
"reference": "d4ca2fb70344987502567bc50081c03e6192fb26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26",
"reference": "d4ca2fb70344987502567bc50081c03e6192fb26",
"shasum": ""
},
"require": {
"php": ">=5.6",
"sebastian/recursion-context": "~2.0"
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
@@ -1258,7 +1377,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "1.0.x-dev"
}
},
"autoload": {
@@ -1278,20 +1397,24 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"time": "2017-02-18T15:18:39+00:00"
"support": {
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/master"
},
"time": "2016-01-28T13:25:10+00:00"
},
{
"name": "sebastian/recursion-context",
"version": "2.0.0",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
"reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
"reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
"reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
"shasum": ""
},
"require": {
@@ -1303,7 +1426,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "1.0.x-dev"
}
},
"autoload": {
@@ -1331,7 +1454,11 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19T07:33:16+00:00"
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/master"
},
"time": "2016-10-03T07:41:43+00:00"
},
{
"name": "sebastian/resource-operations",
@@ -1373,6 +1500,10 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"support": {
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
"source": "https://github.com/sebastianbergmann/resource-operations/tree/master"
},
"time": "2015-07-28T20:34:47+00:00"
},
{
@@ -1416,27 +1547,28 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"support": {
"issues": "https://github.com/sebastianbergmann/version/issues",
"source": "https://github.com/sebastianbergmann/version/tree/master"
},
"time": "2016-10-03T07:35:21+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.24.0",
"version": "v1.19.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b",
"reference": "aed596913b70fae57be53d86faa2e9ef85a2297b",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
"php": ">=5.3.3"
},
"suggest": {
"ext-ctype": "For best performance"
@@ -1444,7 +1576,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.19-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -1452,12 +1584,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1481,6 +1613,9 @@
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -1495,31 +1630,31 @@
"type": "tidelift"
}
],
"time": "2021-10-20T20:35:02+00:00"
"time": "2020-10-23T09:01:57+00:00"
},
{
"name": "symfony/yaml",
"version": "v4.4.37",
"version": "v3.4.47",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311"
"reference": "88289caa3c166321883f67fe5130188ebbb47094"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d7f637cc0f0cc14beb0984f2bb50da560b271311",
"reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311",
"url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094",
"reference": "88289caa3c166321883f67fe5130188ebbb47094",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"php": "^5.5.9|>=7.0.8",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/console": "<3.4"
},
"require-dev": {
"symfony/console": "^3.4|^4.0|^5.0"
"symfony/console": "~3.4|~4.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
@@ -1547,8 +1682,11 @@
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -1563,39 +1701,34 @@
"type": "tidelift"
}
],
"time": "2022-01-24T20:11:01+00:00"
"time": "2020-10-24T10:57:07+00:00"
},
{
"name": "webmozart/assert",
"version": "1.10.0",
"version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
"url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
"php": "^5.3.3 || ^7.0 || ^8.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
"vimeo/psalm": "<4.6.1 || 4.6.2"
"vimeo/psalm": "<3.9.1"
},
"require-dev": {
"phpunit/phpunit": "^8.5.13"
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.10-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -1617,7 +1750,11 @@
"check",
"validate"
],
"time": "2021-03-09T10:59:23+00:00"
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.9.1"
},
"time": "2020-07-08T17:02:28+00:00"
}
],
"aliases": [],
@@ -1629,5 +1766,5 @@
"php": "^5.6.0 || ^7.0 || ^8.0"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
"plugin-api-version": "2.3.0"
}

View File

@@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
body {

View File

@@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
/* When there is no script at all other */

View File

@@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
/* CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved.

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -79,34 +79,34 @@
"Never": "Mai",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
"This document will expire in %d seconds.": [
"This document will expire in %d second. (singular)",
"This document will expire in %d seconds. (1st plural)",
"This document will expire in %d seconds. (2nd plural)",
"This document will expire in %d seconds. (3rd plural)"
"Aquest document caducarà d'aquí %d segon.",
"Aquest document caducarà d'aquí %d segons.",
"Aquest document caducarà d'aquí %d segons.",
"Aquest document caducarà d'aquí %d segons."
],
"This document will expire in %d minutes.": [
"This document will expire in %d minute. (singular)",
"This document will expire in %d minutes. (1st plural)",
"This document will expire in %d minutes. (2nd plural)",
"This document will expire in %d minutes. (3rd plural)"
"Aquest document caducarà d'aquí %d minut.",
"Aquest document caducarà d'aquí %d minuts.",
"Aquest document caducarà d'aquí %d minuts.",
"Aquest document caducarà d'aquí %d minuts."
],
"This document will expire in %d hours.": [
"This document will expire in %d hour. (singular)",
"This document will expire in %d hours. (1st plural)",
"This document will expire in %d hours. (2nd plural)",
"This document will expire in %d hours. (3rd plural)"
"Aquest document caducarà d'aquí %d hora.",
"Aquest document caducarà d'aquí %d hores.",
"Aquest document caducarà d'aquí %d hores.",
"Aquest document caducarà d'aquí %d hores."
],
"This document will expire in %d days.": [
"This document will expire in %d day. (singular)",
"This document will expire in %d days. (1st plural)",
"This document will expire in %d days. (2nd plural)",
"This document will expire in %d days. (3rd plural)"
"Aquest document caducarà d'aquí %d dia.",
"Aquest document caducarà d'aquí %d dies.",
"Aquest document caducarà d'aquí %d dies.",
"Aquest document caducarà d'aquí %d dies."
],
"This document will expire in %d months.": [
"This document will expire in %d month. (singular)",
"This document will expire in %d months. (1st plural)",
"This document will expire in %d months. (2nd plural)",
"This document will expire in %d months. (3rd plural)"
"Aquest document caducarà d'aquí %d mes.",
"Aquest document caducarà d'aquí %d mesos.",
"Aquest document caducarà d'aquí %d mesos.",
"Aquest document caducarà d'aquí %d mesos."
],
"Please enter the password for this paste:": "Si us plau, introdueix la contrasenya per aquest paste:",
"Could not decrypt data (Wrong key?)": "No s'han pogut desxifrar les dades (Clau incorrecte?)",
@@ -124,7 +124,7 @@
"Could not refresh display: %s": "Could not refresh display: %s",
"unknown status": "estat desconegut",
"server error or not responding": "server error or not responding",
"Could not post comment: %s": "Could not post comment: %s",
"Could not post comment: %s": "No s'ha pogut publicar el comentari: %s",
"Sending paste…": "Enviant paste…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
"Delete data": "Esborrar les dades",
@@ -146,7 +146,7 @@
"Download attachment": "Baixar els adjunts",
"Cloned: '%s'": "Cloned: '%s'",
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
"Attach a file": "Attach a file",
"Attach a file": "Adjuntar un fitxer",
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
"File too large, to display a preview. Please download the attachment.": "File too large, to display a preview. Please download the attachment.",
"Remove attachment": "Remove attachment",
@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

193
i18n/co.json Normal file
View File

@@ -0,0 +1,193 @@
{
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s hè un serviziu in linea di tipu « pastebin » (ghjestiunariu dappiccicu di pezzi di testu è di codice di fonte) minimalistu è à fonte aperta induve u servitore ùn hà micca cunnuscenza di i dati mandati. I dati sò cifrati è dicifrati %sin u navigatore%s cù una cifratura AES di 256 bit.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Più dinfurmazione annantà a <a href=\"https://privatebin.info/\">pagina di u prughjettu</a>.",
"Because ignorance is bliss": "Perchè lignurenza hè una campa",
"en": "co",
"Paste does not exist, has expired or has been deleted.": "Lappiccicu ùn esiste micca, hè scadutu o hè statu squassatu.",
"%s requires php %s or above to work. Sorry.": "Per disgrazzia, %s richiede php %s o più recente per funziunà.",
"%s requires configuration section [%s] to be present in configuration file.": "%s richiede a presenza di a sezzione di cunfigurazione [%s] in a schedariu di cunfigurazione.",
"Please wait %d seconds between each post.": [
"Aspettate %d seconda trà dui publicazioni.",
"Aspettate %d seconde trà dui publicazioni.",
"Aspettate %d seconde trà dui publicazioni.",
"Aspettate %d seconde trà dui publicazioni."
],
"Paste is limited to %s of encrypted data.": "Lappiccicu hè limitatu à %s di dati cifrati.",
"Invalid data.": "Dati inaccetevule.",
"You are unlucky. Try again.": "Pruvate torna, Serete più furtunati.",
"Error saving comment. Sorry.": "Per disgrazzia, ci hè un sbagliu à larregistramentu di u cummentu.",
"Error saving paste. Sorry.": "Per disgrazzia, ci hè un sbagliu à larregistramentu di lappiccicu.",
"Invalid paste ID.": "N° di lappiccicu inaccettevule.",
"Paste is not of burn-after-reading type.": "Lappiccicu ùn hè micca di tipu « Squassà dopu a lettura ».",
"Wrong deletion token. Paste was not deleted.": "Gettone di squassatura incurrettu. Lappiccicu ùn hè micca statu squassatu.",
"Paste was properly deleted.": "Lappiccicu hè statu squassatu currettamente.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript hè richiestu per fà funziunà %s. Scusate per stu penseru.",
"%s requires a modern browser to work.": "%s richiede un navigatore mudernu per funziunà.",
"New": "Novu",
"Send": "Mandà",
"Clone": "Duppione",
"Raw text": "Testu grossu",
"Expires": "Scadenza",
"Burn after reading": "Squassà dopu a lettura",
"Open discussion": "Apre una chjachjarata",
"Password (recommended)": "Parolla dintesa (ricumandata)",
"Discussion": "Chjachjarata",
"Toggle navigation": "Invertisce a navigazione",
"%d seconds": [
"%d seconda",
"%d seconde",
"%d seconde",
"%d seconde"
],
"%d minutes": [
"%d minutu",
"%d minuti",
"%d minuti",
"%d minuti"
],
"%d hours": [
"%d ora",
"%d ore",
"%d ore",
"%d ore"
],
"%d days": [
"%d ghjornu",
"%d ghjorni",
"%d ghjorni",
"%d ghjorni"
],
"%d weeks": [
"%d settimana",
"%d settimane",
"%d settimane",
"%d settimane"
],
"%d months": [
"%d mese",
"%d mesi",
"%d mesi",
"%d mesi"
],
"%d years": [
"%d annu",
"%d anni",
"%d anni",
"%d anni"
],
"Never": "Mai",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Nota : Què hè un serviziu di prova ; i dati ponu esse squassati à ogni mumentu. Parechji catorni anu da esse tombi sè vò impiegate troppu stu serviziu.",
"This document will expire in %d seconds.": [
"Stu ducumentu serà scadutu in %d seconda.",
"Stu ducumentu serà scadutu in %d seconde.",
"Stu ducumentu serà scadutu in %d seconde.",
"Stu ducumentu serà scadutu in %d seconde."
],
"This document will expire in %d minutes.": [
"Stu ducumentu serà scadutu in %d minutu.",
"Stu ducumentu serà scadutu in %d minuti.",
"Stu ducumentu serà scadutu in %d minuti.",
"Stu ducumentu serà scadutu in %d minuti."
],
"This document will expire in %d hours.": [
"Stu ducumentu serà scadutu in %d ora.",
"Stu ducumentu serà scadutu in %d ore.",
"Stu ducumentu serà scadutu in %d ore.",
"Stu ducumentu serà scadutu in %d ore."
],
"This document will expire in %d days.": [
"Stu ducumentu serà scadutu in %d ghjornu.",
"Stu ducumentu serà scadutu in %d ghjorni.",
"Stu ducumentu serà scadutu in %d ghjorni.",
"Stu ducumentu serà scadutu in %d ghjorni."
],
"This document will expire in %d months.": [
"Stu ducumentu serà scadutu in %d mese.",
"Stu ducumentu serà scadutu in %d mesi.",
"Stu ducumentu serà scadutu in %d mesi.",
"Stu ducumentu serà scadutu in %d mesi."
],
"Please enter the password for this paste:": "Stampittate a parolla dintesa per stappiccicu :",
"Could not decrypt data (Wrong key?)": "Ùn si pò micca dicifrà i dati ; seria incurretta a chjave ?",
"Could not delete the paste, it was not stored in burn after reading mode.": "Ùn si pò micca squassà lappiccicu, ùn hè micca statu in u modu « Squassà dopu a lettura ».",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "SOLU CÙ LOCHJI. Ùn chjudite micca sta finestra, stu messaghju un puderà più esse affissatu torna.",
"Could not decrypt comment; Wrong key?": "Ùn si pò micca dicifrà u cummentu. Seria incurretta a chjave ?",
"Reply": "Risponde",
"Anonymous": "Anonimu",
"Avatar generated from IP address": "Avatar ingeneratu da lindirizzu IP",
"Add comment": "Aghjunghje un cummentu",
"Optional nickname…": "Cugnome ozzionale…",
"Post comment": "Impustà u cummentu",
"Sending comment…": "Inviu di u cummentu…",
"Comment posted.": "Cummentu inviatu.",
"Could not refresh display: %s": "Ùn si pò micca attualizà laffissera : %s",
"unknown status": "statu scunnisciutu",
"server error or not responding": "sbagliu di u servitore o u servitore ùn risponde micca",
"Could not post comment: %s": "Ùn si pò micca impustà u cummentu : %s",
"Sending paste…": "Inviu di lappiccicu…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "U vostru appiccicu si trova à lindirizzu<a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appughjate [Ctrl]+[c] per cupià u liame)</span>",
"Delete data": "Squassà i dati",
"Could not create paste: %s": "Ùn si pò micca creà lappiccicu : %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Ùn si pò micca dicifrà lappiccicu : A chjave di dicifratura hè assente in lindirizzu. Averiate impiegatu un orientadore dindirizzu o un riduttore chì ammuzzeghja una parte di lindirizzu ?",
"B": "o",
"KiB": "Ko",
"MiB": "Mo",
"GiB": "Go",
"TiB": "To",
"PiB": "Po",
"EiB": "Eo",
"ZiB": "Zo",
"YiB": "Yo",
"Format": "Furmatu",
"Plain Text": "Testu in chjaru",
"Source Code": "Codice di fonte",
"Markdown": "Markdown",
"Download attachment": "Scaricà a pezza aghjunta",
"Cloned: '%s'": "Duppiatu : « %s »",
"The cloned file '%s' was attached to this paste.": "U schedariu duppiatu « %s » hè statu aghjuntu à stappiccicu.",
"Attach a file": "Aghjunghje un schedariu",
"alternatively drag & drop a file or paste an image from the clipboard": "in alternanza, sguillà è depone un schedariu o incullà una fiura da u premepapei",
"File too large, to display a preview. Please download the attachment.": "Schedariu troppu maiò per affissà una fighjulata. Scaricate a pezza aghjunta.",
"Remove attachment": "Caccià a pezza aghjunta",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "U vostru navigatore ùn accetta micca linviu di i schedarii cifrati. Impiegate un navigatore più recente.",
"Invalid attachment.": "A pezza aghjunta hè inaccettevule.",
"Options": "Ozzioni",
"Shorten URL": "Ammuzzà lindirizzu",
"Editor": "Editore",
"Preview": "Fighjulata",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s richiede chì a variabile PATH si compii cù « %s ». Mudificate a variabile PATH in u vostru index.php.",
"Decrypt": "Dicifrà",
"Enter password": "Stampittate a parolla dintesa",
"Loading…": "Caricamentu…",
"Decrypting paste…": "Dicifratura di lappiccicu…",
"Preparing new paste…": "Approntu di u novu appiccicu…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "Sè stu messaghju ùn smarisce micca, lighjite <a href=\"%s\">sta FAQ per ottene infurmazioni annantà a risuluzione di i prublemi</a>.",
"+++ no paste text +++": "+++ nisunu testu incullatu +++",
"Could not get paste data: %s": "Ùn si pò micca ottene i dati di lappiccicu : %s",
"QR code": "Codice QR",
"This website is using an insecure HTTP connection! Please use it only for testing.": "Stu situ web impiegheghja una cunnessione HTTP non sicura ! impiegatelu solu per una prova.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Per sapene di più, <a href=\"%s\">lighjite sta rubrica di a FAQ</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "U vostru navigatore pò richiede una cunnessione HTTPS per permette lusu di lAPI WebCrypto. Pruvate di <a href=\"%s\">passà à HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "U vostru navigatore ùn accetta micca WebAssembly, impiegatu per a cumpressione zlib. Pudete creà ducumenti micca cumpressi, ma ùn pudete micca leghje quelli chì sò cumpressi.",
"waiting on user to provide a password": "in attesa di lutilizatore per furnisce una parolla dintesa",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Ùn si pò micca dicifrà i dati. Avete stampittatu una parolla dintesa incurretta ? Pruvate torna cù u buttone insù.",
"Retry": "Pruvà torna",
"Showing raw text…": "Affissera di u testu grossu…",
"Notice:": "Avertimentu :",
"This link will expire after %s.": "Stu liame hà da scade dopu à %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Stu liame pò esse accessu solu una volta, ùn impiegate micca i buttoni Precedente o Attualizà di u vostru navigatore.",
"Link:": "Liame :",
"Recipient may become aware of your timezone, convert time to UTC?": "U destinatariu pò cunnnosce u vostru fusu orariu. Vulete cunvertisce lora in u furmatu UTC ?",
"Use Current Timezone": "Impiegà u fusu orariu attuale",
"Convert To UTC": "Cunvertisce in UTC",
"Close": "Chjode",
"Encrypted note on %s": "Nota cifrata nantà %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visitate stu liame per vede a nota. Date lindirizzu à qualunque li permette daccede à a nota dinù.",
"URL shortener may expose your decrypt key in URL.": "Un ammuzzatore dindirizzu pò palisà a vostra chjave di dicifratura in lindirizzu.",
"Save paste": "Arregistrà lappiccicu",
"Your IP is not authorized to create pastes.": "U vostru indirizzu IP ùn hè micca auturizatu à creà lappiccichi.",
"Trying to shorten a URL that isn't pointing at our instance.": "Pruvate dammuzzà un indirizzu web chì ùn punta micca versu a vostra instanza.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Sbagliu à a chjama di YOURLS. Seria forse una cunfigurazione gattiva, tale una \"apiurl\" o \"signature\" falsa o assente.",
"Error parsing YOURLS response.": "Sbagliu durante lanalisa di a risposta di YOURLS."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Použít aktuální časové pásmo",
"Convert To UTC": "Převést na UTC",
"Close": "Zavřít",
"Encrypted note on PrivateBin": "Šifrovaná poznámka ve službě PrivateBin",
"Encrypted note on %s": "Šifrovaná poznámka ve službě %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Navštivte tento odkaz pro zobrazení poznámky. Přeposláním URL umožníte také jiným lidem přístup.",
"URL shortener may expose your decrypt key in URL.": "Zkracovač URL může odhalit váš dešifrovací klíč v URL.",
"Save paste": "Uložit příspěvek"
"Save paste": "Uložit příspěvek",
"Your IP is not authorized to create pastes.": "Vaše IP adresa nemá oprávnění k vytvoření vložení.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Aktuelle Zeitzone verwenden",
"Convert To UTC": "In UTC umwandeln",
"Close": "Schliessen",
"Encrypted note on PrivateBin": "Verschlüsselte Notiz auf PrivateBin",
"Encrypted note on %s": "Verschlüsselte Notiz auf %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Besuche diesen Link um das Dokument zu sehen. Wird die URL an eine andere Person gegeben, so kann diese Person ebenfalls auf dieses Dokument zugreifen.",
"URL shortener may expose your decrypt key in URL.": "Der URL-Verkürzer kann den Schlüssel in der URL enthüllen.",
"Save paste": "Text speichern"
"Save paste": "Text speichern",
"Your IP is not authorized to create pastes.": "Deine IP ist nicht berechtigt, Texte zu erstellen.",
"Trying to shorten a URL that isn't pointing at our instance.": "Versuch eine URL zu verkürzen, die nicht auf unsere Instanz zeigt.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Fehler beim Aufruf von YOURLS. Wahrscheinlich ein Konfigurationsproblem, wie eine falsche oder fehlende \"apiurl\" oder \"signature\".",
"Error parsing YOURLS response.": "Fehler beim Verarbeiten der YOURLS-Antwort."
}

View File

@@ -1,135 +1,135 @@
{
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "More information on the <a href=\"https://privatebin.info/\">project page</a>.",
"Because ignorance is bliss": "Because ignorance is bliss",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s είναι ένα λιτό, ανοικτού λογισμικού διαδικτυακής υπηρεσίας επικόλλησης όπου ο διακομιστής έχει πλήρη άγνια του περιεχομένου που επικολλήθηκαν. Τα Δεδομένα κρυπτογραφούνται και αποκρυπτογραφούνται %sστον φιλομετρητή (browser)%s χρησιμοποιόντας 256 bits AES.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Περισσότερες πληροφορίες στον <a href=\"https://privatebin.info/\">ιστότοπο του εργαλείου</a>.",
"Because ignorance is bliss": "Επειδή η άγνοια είναι ευτυχία",
"en": "el",
"Paste does not exist, has expired or has been deleted.": "Paste does not exist, has expired or has been deleted.",
"%s requires php %s or above to work. Sorry.": "%s requires php %s or above to work. Sorry.",
"%s requires configuration section [%s] to be present in configuration file.": "%s requires configuration section [%s] to be present in configuration file.",
"Paste does not exist, has expired or has been deleted.": "Η επικόλληση δεν υπάρχει, έληξε ή διαγράφηκε",
"%s requires php %s or above to work. Sorry.": "%s απαιτεί php %s ή νεότερη για να λειτουργήσει. Συγγνώμη.",
"%s requires configuration section [%s] to be present in configuration file.": "%s απαιτεί οι ρυθμίσεις [%s] να υπάρχουν στο αρχείο ρυθμίσεων.",
"Please wait %d seconds between each post.": [
"Please wait %d second between each post. (singular)",
"Please wait %d seconds between each post. (1st plural)",
"Please wait %d seconds between each post. (2nd plural)",
"Please wait %d seconds between each post. (3rd plural)"
"Παρακαλώ περιμένετε %d δευτερόλεπτο μεταξύ κάθε επικόλλησης.",
"Παρακαλώ περιμένετε %d δευτερόλεπτα μεταξύ κάθε επικόλλησης.",
"Παρακαλώ περιμένετε %d δευτερόλεπτα μεταξύ κάθε επικόλλησης.",
"Παρακαλώ περιμένετε %d δευτερόλεπτα μεταξύ κάθε επικόλλησης."
],
"Paste is limited to %s of encrypted data.": "Paste is limited to %s of encrypted data.",
"Invalid data.": "Invalid data.",
"You are unlucky. Try again.": "You are unlucky. Try again.",
"Error saving comment. Sorry.": "Error saving comment. Sorry.",
"Error saving paste. Sorry.": "Error saving paste. Sorry.",
"Invalid paste ID.": "Invalid paste ID.",
"Paste is not of burn-after-reading type.": "Paste is not of burn-after-reading type.",
"Wrong deletion token. Paste was not deleted.": "Wrong deletion token. Paste was not deleted.",
"Paste was properly deleted.": "Paste was properly deleted.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript is required for %s to work. Sorry for the inconvenience.",
"%s requires a modern browser to work.": "%s requires a modern browser to work.",
"New": "New",
"Send": "Send",
"Clone": "Clone",
"Raw text": "Raw text",
"Expires": "Expires",
"Burn after reading": "Burn after reading",
"Open discussion": "Open discussion",
"Password (recommended)": "Password (recommended)",
"Discussion": "Discussion",
"Toggle navigation": "Toggle navigation",
"Paste is limited to %s of encrypted data.": "Η επικόλληση είναι περιορισμένη σε %s κρυπτογραφημένων δεδομένων.",
"Invalid data.": "Λάθος δεδομένα.",
"You are unlucky. Try again.": "Ατυχήσατε. Προσπαθήστε πάλι.",
"Error saving comment. Sorry.": "Λάθος στην αποθήκευση του σχόλιου. Συγγνώμη.",
"Error saving paste. Sorry.": "Λάθος στην αποθήκευση της επικόλλησης. Συγγνώμη.",
"Invalid paste ID.": "Λάθος αναγνωριστικό επικόλλησης.",
"Paste is not of burn-after-reading type.": "Η επικόληση δεν είναι τύπου καταστροφή-μετά-το-διάβασμα.",
"Wrong deletion token. Paste was not deleted.": "Λάθος αναγνωριστικό διαγραφής. Η επικόλληση δεν διαγράφηκε.",
"Paste was properly deleted.": "Η επικόλληση διαγράφηκε επιτυχώς.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "Η JavaScript είναι απαραίτητη για να λειτουργήσει το %s. Συγγνώμη για την ταλαιπωρία.",
"%s requires a modern browser to work.": "%s απαιτεί σύγχρονο φυλλομετρητή (browser) για να λειτουργήσει.",
"New": "Νέο",
"Send": "Αποστολή",
"Clone": "Κλωνοποίηση",
"Raw text": "Κείμενο",
"Expires": "Λήγει",
"Burn after reading": "Διαγραφή μετά την ανάγνωση",
"Open discussion": "Ανοικτή συζήτηση",
"Password (recommended)": "Κωδικός (προτείνεται)",
"Discussion": "Συζήτηση",
"Toggle navigation": "Εναλλαγή πλοήγησης",
"%d seconds": [
"%d second (singular)",
"%d seconds (1st plural)",
"%d seconds (2nd plural)",
"%d seconds (3rd plural)"
"%d δευτερόλεπτο",
"%d δευτερόλεπτα",
"%d δευτερόλεπτα",
"%d δευτερόλεπτα"
],
"%d minutes": [
"%d minute (singular)",
"%d minutes (1st plural)",
"%d minutes (2nd plural)",
"%d minutes (3rd plural)"
"%d λεπτό",
"%d λεπτά",
"%d λεπτά",
"%d λεπτά"
],
"%d hours": [
"%d hour (singular)",
"%d hours (1st plural)",
"%d hours (2nd plural)",
"%d hours (3rd plural)"
"%d ώρα",
"%d ώρες",
"%d ώρες",
"%d ώρες"
],
"%d days": [
"%d day (singular)",
"%d days (1st plural)",
"%d days (2nd plural)",
"%d days (3rd plural)"
"%d ημέρα",
"%d ημέρες",
"%d ημέρες",
"%d ημέρες"
],
"%d weeks": [
"%d week (singular)",
"%d weeks (1st plural)",
"%d weeks (2nd plural)",
"%d weeks (3rd plural)"
"%d εβδομάδα",
"%d εβδομάδες",
"%d εβδομάδες",
"%d εβδομάδες"
],
"%d months": [
"%d month (singular)",
"%d months (1st plural)",
"%d months (2nd plural)",
"%d months (3rd plural)"
"%d μήνας",
"%d μήνες",
"%d μήνες",
"%d μήνες"
],
"%d years": [
"%d year (singular)",
"%d years (1st plural)",
"%d years (2nd plural)",
"%d years (3rd plural)"
"%d χρόνο",
"%d χρόνια",
"%d χρόνια",
"%d χρόνια"
],
"Never": "Never",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
"Never": "Ποτέ",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Σημείωση: αυτή είναι μία δοκιμαστική υπηρεσία. Τα δεδομένα μπορεί να σβηστούν ανά πάσα στιγμή.",
"This document will expire in %d seconds.": [
"This document will expire in %d second. (singular)",
"This document will expire in %d seconds. (1st plural)",
"This document will expire in %d seconds. (2nd plural)",
"This document will expire in %d seconds. (3rd plural)"
"Αυτό το έγγραφο θα λήξει σε %d δευτερόλεπτο.",
"Αυτό το έγγραφο θα λήξει σε %d δευτερόλεπτα.",
"Αυτό το έγγραφο θα λήξει σε %d δευτερόλεπτα.",
"Αυτό το έγγραφο θα λήξει σε %d δευτερόλεπτα."
],
"This document will expire in %d minutes.": [
"This document will expire in %d minute. (singular)",
"This document will expire in %d minutes. (1st plural)",
"This document will expire in %d minutes. (2nd plural)",
"This document will expire in %d minutes. (3rd plural)"
"Αυτό το έγγραφο θα λήξει σε %d λεπτό.",
"Αυτό το έγγραφο θα λήξει σε %d λεπτά.",
"Αυτό το έγγραφο θα λήξει σε %d λεπτά.",
"Αυτό το έγγραφο θα λήξει σε %d λεπτά."
],
"This document will expire in %d hours.": [
"This document will expire in %d hour. (singular)",
"This document will expire in %d hours. (1st plural)",
"This document will expire in %d hours. (2nd plural)",
"This document will expire in %d hours. (3rd plural)"
"Αυτό το έγγραφο θα λήξει σε %d ώρα.",
"Αυτό το έγγραφο θα λήξει σε %d ώρες.",
"Αυτό το έγγραφο θα λήξει σε %d ώρες.",
"Αυτό το έγγραφο θα λήξει σε %d ώρες."
],
"This document will expire in %d days.": [
"This document will expire in %d day. (singular)",
"This document will expire in %d days. (1st plural)",
"This document will expire in %d days. (2nd plural)",
"This document will expire in %d days. (3rd plural)"
"Αυτό το έγγραφο θα λήξει σε %d ημέρα.",
"Αυτό το έγγραφο θα λήξει σε %d ημέρες.",
"Αυτό το έγγραφο θα λήξει σε %d ημέρες.",
"Αυτό το έγγραφο θα λήξει σε %d ημέρες."
],
"This document will expire in %d months.": [
"This document will expire in %d month. (singular)",
"This document will expire in %d months. (1st plural)",
"This document will expire in %d months. (2nd plural)",
"This document will expire in %d months. (3rd plural)"
"Αυτό το έγγραφο θα λήξει σε %d μήνα.",
"Αυτό το έγγραφο θα λήξει σε %d μήνες.",
"Αυτό το έγγραφο θα λήξει σε %d μήνες.",
"Αυτό το έγγραφο θα λήξει σε %d μήνες."
],
"Please enter the password for this paste:": "Please enter the password for this paste:",
"Could not decrypt data (Wrong key?)": "Could not decrypt data (Wrong key?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
"Reply": "Reply",
"Anonymous": "Anonymous",
"Avatar generated from IP address": "Avatar generated from IP address",
"Add comment": "Add comment",
"Optional nickname…": "Optional nickname…",
"Post comment": "Post comment",
"Sending comment…": "Sending comment…",
"Comment posted.": "Comment posted.",
"Could not refresh display: %s": "Could not refresh display: %s",
"unknown status": "unknown status",
"server error or not responding": "server error or not responding",
"Could not post comment: %s": "Could not post comment: %s",
"Sending paste…": "Sending paste…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
"Delete data": "Delete data",
"Could not create paste: %s": "Could not create paste: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
"Please enter the password for this paste:": "Παρακαλώ εισάγετε τον κωδικό για αυτή την επικόληση:",
"Could not decrypt data (Wrong key?)": "Δεν ήταν δυνατή η αποκρυπτογράφηση των δεδομένων (πιθανώς λανθασμένο κλειδί;)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Δεν ήταν δυνατή η διαγραφή της επικόλλησης, δεν ήταν αποθηκευμένη σε μορφή διαγραφής μετά την ανάγνωση.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "ΜΟΝΟ ΓΙΑ ΕΣΑΣ. Μην κλείσετε το αυτό το παράθυρο, αυτό το μήνυμα δεν μπορεί να εμφανιστεί ξανά.",
"Could not decrypt comment; Wrong key?": "Δεν ήταν δυνατή η αποκρυπτογράφηση του σχολίου. Λάθος κλειδί;",
"Reply": "Απάντηση",
"Anonymous": "Ανώνυμος",
"Avatar generated from IP address": "το avatar δημιουργήθηκε από τη διεύθυνση IP",
"Add comment": "Σχολιάστε",
"Optional nickname…": "Προαιρετικό ψευδώνυμο…",
"Post comment": "Αποστολή σχολίου",
"Sending comment…": "Το σχόλιο αποστέλλεται…",
"Comment posted.": "Το σχόλιο δημοσιεύτηκε.",
"Could not refresh display: %s": "Δεν ήταν δυνατή η ανανέωση της σελίδας: %s",
"unknown status": "άγνωστη κατάσταση",
"server error or not responding": "Πρόβλημα του διακομιστή ή δεν υπάρχει απάντηση",
"Could not post comment: %s": "Δεν ήταν δυνατή η δημοσίευση του σχολίου: %s",
"Sending paste…": "Η επικόλληση αποστέλλεται…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Η επικόλλησή σας είναι <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Πληκτρολογήστε [Ctrl]+[c] για αντιγραφή)</span>",
"Delete data": "Διαγραφή δεδομένων",
"Could not create paste: %s": "Δεν ήταν δυνατή η δημιουργία επικόλλησης: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Δεν ήταν δυνατή η αποκρυπτογράφηση της επικόλλησης: Το κλειδί αποκρυπτογράφησης λείπει από τον σύνδεσμο (Μήπως χρησιμοποιήσατε ανακατεύθυνση συνδέσμου ή υπηρεσία συντόμευσης συνδέσμου;)",
"B": "B",
"KiB": "KiB",
"MiB": "MiB",
@@ -139,51 +139,55 @@
"EiB": "EiB",
"ZiB": "ZiB",
"YiB": "YiB",
"Format": "Format",
"Plain Text": "Plain Text",
"Source Code": "Source Code",
"Format": "Μορφοποίηση",
"Plain Text": "Απλό κείμενο",
"Source Code": "Πηγαίος Κώδικας",
"Markdown": "Markdown",
"Download attachment": "Download attachment",
"Cloned: '%s'": "Cloned: '%s'",
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
"Attach a file": "Attach a file",
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
"File too large, to display a preview. Please download the attachment.": "File too large, to display a preview. Please download the attachment.",
"Remove attachment": "Remove attachment",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Your browser does not support uploading encrypted files. Please use a newer browser.",
"Invalid attachment.": "Invalid attachment.",
"Options": "Options",
"Shorten URL": "Shorten URL",
"Editor": "Editor",
"Preview": "Preview",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
"Decrypt": "Decrypt",
"Enter password": "Enter password",
"Loading…": "Loading…",
"Decrypting paste…": "Decrypting paste…",
"Preparing new paste…": "Preparing new paste…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
"+++ no paste text +++": "+++ no paste text +++",
"Could not get paste data: %s": "Could not get paste data: %s",
"QR code": "QR code",
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
"waiting on user to provide a password": "waiting on user to provide a password",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
"Retry": "Retry",
"Showing raw text…": "Showing raw text…",
"Notice:": "Notice:",
"This link will expire after %s.": "This link will expire after %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
"Link:": "Link:",
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Download attachment": "Λήψη επισυναπτόμενου",
"Cloned: '%s'": "Κλώνος: '%s'",
"The cloned file '%s' was attached to this paste.": "Το κλωνοποιημένο αρχείο '%s' επισυνάφθηκε στ αυτή την επικόλληση.",
"Attach a file": "Επισύναψη αρχείου",
"alternatively drag & drop a file or paste an image from the clipboard": "εναλλακτικά σύρετε το αρχείο ή επικολλήστε μία εικόνα από το clipboard",
"File too large, to display a preview. Please download the attachment.": "Πολύ μεγάλο αρχείο για προεπισκόπηση. Παρακαλώ κατεβάστε το επισυναπτόμενο.",
"Remove attachment": "Αφαίρεση επισυναπτόμενου",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Ο φυλλομετρητής (browser) σας δεν υποστηρίζει κρυπτογραφημένα αρχεία. Παρακαλώ χρησιμοποιήστε νεότερο φιλομετρητή.",
"Invalid attachment.": "Λάθος επισυναπτόμενο.",
"Options": "Επιλογές",
"Shorten URL": "Συντόμευση σύνδεσμου",
"Editor": "Διορθωτής",
"Preview": "Προεπισκόπηση",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s απαιτεί το PATH να τελειώνει σε \"%s\". Παρακαλώ ενημερώστε το PATH στο index.php σας.",
"Decrypt": "Αποκρυπτογράφηση",
"Enter password": "Εισαγωγή κωδικού",
"Loading…": "Φόρτωση…",
"Decrypting paste…": "Η επικόλληση αποκρυπτογραφείται…",
"Preparing new paste…": "Προετοιμασία νέας επικόλλησης…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "Σε περίπτωση που αυτό το μήνυμα δεν εξαφανίζεται παρακαλώ κοιτάξτε στις <a href=\"%s\">Ερωταποκρίσεις για πληροφορίες στην αντιμετώπιση προβλημάτων</a>.",
"+++ no paste text +++": "+++ Δεν υπάρχει επικόλληση +++",
"Could not get paste data: %s": "Δεν ήταν δυνατή η λήψη της επικόλλησης: %s",
"QR code": "QR εικονοστοιχειοσειρά",
"This website is using an insecure HTTP connection! Please use it only for testing.": "Αυτός ο ιστότοπος χρησιμοποιεί μη ασφαλή HTTP σύνδεση! Παρακαλώ χρησιμοποιήστε το μόνο δοκιμαστικά.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Για περισσότερες πληροφορίες <a href=\"%s\">δείτε τις ερωταπαντήσεις</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Ο φυλλομετρητής σας μπορεί να απαιτεί HTTPS σύνδεση για να υποστηρίξει το WebCrypto API. Δοκιμάστε <a href=\"%s\">το HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Ο φυλλομετρητής σας δεν υποστηρίζει WebAssembly, που χρησιμοποιήθηκε για zlib συμπίεση. Μπορείτε να δημιουργήσετε ασυμπίεστα αρχεία αλλά δεν μπορείτε να διαβάσετε συμπιεσμένα.",
"waiting on user to provide a password": "Αναμονή ο χρήστης να δώσει τον κωδικό",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Δεν ήταν δυνατή η αποκρυπτογράφηση των δεδομένων. Μήπως εισάγατε λάθος κωδικό; Προσπαθήστε με το κουμπί στο επάνω μέρος.",
"Retry": "Επαναπροσπάθεια",
"Showing raw text…": "Προβολή κειμένου…",
"Notice:": "Επισήμανση:",
"This link will expire after %s.": "Ο σύνδεσμος θα λήξει σε %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Αυτός ο σύνδεσμος μπορεί να προσπελαστεί μόνο μία φορά, μην χρησιμοποιήσετε το κουμπί επιστροφή ή ανανέωση στον φυλλομετρητή σας.",
"Link:": "Σύνδεσμος:",
"Recipient may become aware of your timezone, convert time to UTC?": "Ο παραλήπτης μπορεί να αναγνωρίσει τη ζώνη ώρας σας, θέλετε μετατροπή της ώρας σε UTC;",
"Use Current Timezone": "Χρήση τρέχουσας ζώνης ώρας",
"Convert To UTC": "Μετατροπή σε UTC",
"Close": "Κλείσιμο",
"Encrypted note on %s": "Κρυπτογραφημένο μήνυμα από το %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Επισκεφτείτε αυτόν τον σύνδεσμο για να δείτε το μήνυμα. Δίνοντας τον σύνδεσμο σε οποιονδήποτε, του επιτρέπετε να επισκεφτεί το μήνυμα επίσης.",
"URL shortener may expose your decrypt key in URL.": "Συντομευτές συνδέσμων πιθανώς να δημοσιοποιήσουν το κλειδί αποκρυπτογράφισης στον σύνδεσμο.",
"Save paste": "Αποθήκευση επικόλλησης",
"Your IP is not authorized to create pastes.": "Η IP σας δεν επιτρέπεται να δημιουργεί επικολλήσεις.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -2,7 +2,7 @@
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s es un \"pastebin\" en línea minimalista de código abierto, donde el servidor no tiene ningún conocimiento de los datos guardados. Los datos son cifrados/descifrados %sen el navegador%s usando 256 bits AES.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Más información en la <a href=\"https://privatebin.info/\">página del proyecto</a>.",
"Because ignorance is bliss": "Porque la ignorancia es dicha",
"Because ignorance is bliss": "Porque la ignorancia es felicidad",
"en": "es",
"Paste does not exist, has expired or has been deleted.": "El \"paste\" no existe, ha caducado o ha sido eliminado.",
"%s requires php %s or above to work. Sorry.": "%s requiere php %s o superior para funcionar. Lo siento.",
@@ -182,8 +182,12 @@
"Use Current Timezone": "Usar Zona Horaria Actual",
"Convert To UTC": "Convertir A UTC",
"Close": "Cerrar",
"Encrypted note on PrivateBin": "Nota cifrada en PrivateBin",
"Encrypted note on %s": "Nota cifrada en %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visite este enlace para ver la nota. Dar la URL a cualquier persona también les permite acceder a la nota.",
"URL shortener may expose your decrypt key in URL.": "El acortador de URL puede exponer su clave de descifrado en el URL.",
"Save paste": "Guardar \"paste\""
"Save paste": "Guardar \"paste\"",
"Your IP is not authorized to create pastes.": "Tu IP no está autorizada para crear contenido.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Kasuta praegust ajavööndit",
"Convert To UTC": "Teisenda UTC-ks",
"Close": "Sulge",
"Encrypted note on PrivateBin": "Krüpteeritud kiri PrivateBin-is",
"Encrypted note on %s": "Krüpteeritud kiri %s-is",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Kirja nägemiseks külasta seda linki. Teistele URL-i andmine lubab ka neil ligi pääseda kirjale.",
"URL shortener may expose your decrypt key in URL.": "URL-i lühendaja võib paljastada sinu dekrüpteerimisvõtme URL-is.",
"Save paste": "Salvesta kleebe"
"Save paste": "Salvesta kleebe",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -15,11 +15,11 @@
],
"Paste is limited to %s of encrypted data.": "Paste on rajoitettu kokoon %s salattua dataa.",
"Invalid data.": "Virheellinen data.",
"You are unlucky. Try again.": "Olet epäonnekas. Yritä uudelleen",
"You are unlucky. Try again.": "Olet epäonnekas. Yritä uudelleen.",
"Error saving comment. Sorry.": "Virhe kommenttia tallentaessa. Anteeksi.",
"Error saving paste. Sorry.": "Virhe pastea tallentaessa. Anteeksi.",
"Invalid paste ID.": "Virheellinen paste ID.",
"Paste is not of burn-after-reading type.": "Paste ei ole polta-lukemisen-jälkeen-tyyppiä",
"Paste is not of burn-after-reading type.": "Paste ei ole polta-lukemisen-jälkeen-tyyppiä.",
"Wrong deletion token. Paste was not deleted.": "Virheellinen poistotunniste. Pastea ei poistettu.",
"Paste was properly deleted.": "Paste poistettiin kunnolla.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScriptiä tarvitaan jotta %s toimisi. Anteeksi haitasta.",
@@ -182,8 +182,12 @@
"Use Current Timezone": "Käytä nykyistä aikavyöhykettä",
"Convert To UTC": "Muuta UTC:ksi",
"Close": "Sulje",
"Encrypted note on PrivateBin": "Salattu viesti PrivateBinissä",
"Encrypted note on %s": "Salattu viesti %sissä",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Käy tässä linkissä nähdäksesi viestin. URL:n antaminen kenellekään antaa heidänkin päästä katsomeen viestiä. ",
"URL shortener may expose your decrypt key in URL.": "URL-lyhentäjä voi paljastaa purkuavaimesi URL:ssä.",
"Save paste": "Tallenna paste"
"Save paste": "Tallenna paste",
"Your IP is not authorized to create pastes.": "IP:llesi ei ole annettu oikeutta luoda pasteja.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -2,7 +2,7 @@
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s est un 'pastebin' (ou gestionnaire d'extraits de texte et de code source) minimaliste et open source, dans lequel le serveur n'a aucune connaissance des données envoyées. Les données sont chiffrées/déchiffrées %sdans le navigateur%s par un chiffrement AES 256 bits.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Plus d'informations sur <a href=\"https://privatebin.info/\">la page du projet</a>.",
"Because ignorance is bliss": "Parce que l'ignorance c'est le bonheur",
"Because ignorance is bliss": "Vivons heureux, vivons cachés",
"en": "fr",
"Paste does not exist, has expired or has been deleted.": "Le paste n'existe pas, a expiré, ou a été supprimé.",
"%s requires php %s or above to work. Sorry.": "Désolé, %s nécessite php %s ou supérieur pour fonctionner.",
@@ -182,8 +182,12 @@
"Use Current Timezone": "Conserver l'actuel",
"Convert To UTC": "Convertir en UTC",
"Close": "Fermer",
"Encrypted note on PrivateBin": "Message chiffré sur PrivateBin",
"Encrypted note on %s": "Message chiffré sur %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visiter ce lien pour voir la note. Donner l'URL à une autre personne lui permet également d'accéder à la note.",
"URL shortener may expose your decrypt key in URL.": "Raccourcir l'URL peut exposer votre clé de déchiffrement dans l'URL.",
"Save paste": "Sauver le paste"
"Save paste": "Sauver le paste",
"Your IP is not authorized to create pastes.": "Votre adresse IP n'est pas autorisée à créer des pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "להשתמש באזור הזמן הנוכחי",
"Convert To UTC": "המרה ל־UTC",
"Close": "סגירה",
"Encrypted note on PrivateBin": "הערה מוצפנת ב־PrivateBin",
"Encrypted note on %s": "%sהערה מוצפנת ב־",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "נא לבקר בקישור כדי לצפות בהערה. מסירת הקישור לאנשים כלשהם תאפשר גם להם לגשת להערה.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Az aktuális időzóna használata",
"Convert To UTC": "Átalakítás UTC időzónára",
"Close": "Bezárás",
"Encrypted note on PrivateBin": "Titkosított jegyzet a PrivateBinen",
"Encrypted note on %s": "Titkosított jegyzet a %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Látogasd meg ezt a hivatkozást a bejegyzés megtekintéséhez. Ha mások számára is megadod ezt a linket, azzal hozzáférnek ők is.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Gunakan Zonawaktu Saat Ini",
"Convert To UTC": "Konversi Ke UTC",
"Close": "Tutup",
"Encrypted note on PrivateBin": "Catatan ter-ekrip di PrivateBin",
"Encrypted note on %s": "Catatan ter-ekrip di %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Kunjungi tautan ini untuk melihat catatan. Memberikan alamat URL pada siapapun juga, akan mengizinkan mereka untuk mengakses catatan, so pasti gitu loh Kaka.",
"URL shortener may expose your decrypt key in URL.": "Pemendek URL mungkin akan menampakkan kunci dekrip Anda dalam URL.",
"Save paste": "Simpan paste"
"Save paste": "Simpan paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Usa Fuso Orario Corrente",
"Convert To UTC": "Converti a UTC",
"Close": "Chiudi",
"Encrypted note on PrivateBin": "Nota crittografata su PrivateBin",
"Encrypted note on %s": "Nota crittografata su %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visita questo collegamento per vedere la nota. Dare l'URL a chiunque consente anche a loro di accedere alla nota.",
"URL shortener may expose your decrypt key in URL.": "URL shortener può esporre la tua chiave decrittografata nell'URL.",
"Save paste": "Salva il messagio"
"Save paste": "Salva il messagio",
"Your IP is not authorized to create pastes.": "Il tuo IP non è autorizzato a creare dei messaggi.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "galfi lo cabni la utc",
"Close": "ganlo",
"Encrypted note on PrivateBin": ".i lo lo notci ku mifra cu zvati sivlolnitvanku'a",
"Encrypted note on %s": ".i lo lo notci ku mifra cu zvati %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "rejgau fukpi"
"Save paste": "rejgau fukpi",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Naudoti esamą laiko juostą",
"Convert To UTC": "Konvertuoti į UTC",
"Close": "Užverti",
"Encrypted note on PrivateBin": "Šifruoti užrašai ties PrivateBin",
"Encrypted note on %s": "Šifruoti užrašai ties %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Norėdami matyti užrašus, aplankykite šį tinklalapį. Pasidalinus šiuo URL adresu su kitais žmonėmis, jiems taip pat bus leidžiama prieiga prie šių užrašų.",
"URL shortener may expose your decrypt key in URL.": "URL trumpinimo įrankis gali atskleisti URL adrese jūsų iššifravimo raktą.",
"Save paste": "Įrašyti įdėjimą"
"Save paste": "Įrašyti įdėjimą",
"Your IP is not authorized to create pastes.": "Jūsų IP adresas neturi įgaliojimų kurti įdėjimų.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -35,7 +35,7 @@
"Discussion": "Discussie",
"Toggle navigation": "Navigatie openen/sluiten",
"%d seconds": [
"%d second",
"%d seconde",
"%d seconden",
"%d seconds (2nd plural)",
"%d seconds (3rd plural)"
@@ -72,14 +72,14 @@
],
"%d years": [
"%d jaar",
"%d jaaren",
"%d jaren",
"%d years (2nd plural)",
"%d years (3rd plural)"
],
"Never": "Nooit",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Opmerking: Dit is een testservice: Gegevens kunnen op elk gegeven moment verwijderd worden.",
"This document will expire in %d seconds.": [
"Dit document verloopt over %d second.",
"Dit document verloopt over %d seconde.",
"Dit document verloopt over %d seconden.",
"Dit document verloopt over %d seconden.",
"Dit document verloopt over %d seconden."
@@ -108,7 +108,7 @@
"Dit document verloopt over %d maanden.",
"Dit document verloopt over %d maanden."
],
"Please enter the password for this paste:": "Voer het wachtwoord in voor deze geplakte tekst:",
"Please enter the password for this paste:": "Voer het wachtwoord in voor deze geplakte tekst:",
"Could not decrypt data (Wrong key?)": "Kon de gegevens niet decoderen (verkeerde sleutel?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Verwijderen van de geplakte tekst niet mogelijk, deze werd niet opgeslagen in 'vernietig na lezen' modus.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Sluit dit venster niet, dit bericht kan niet opnieuw worden weergegeven.",
@@ -129,7 +129,7 @@
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Uw geplakte tekst is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Druk [Ctrl]+[c] om te kopiëren)</span>",
"Delete data": "Gegevens wissen",
"Could not create paste: %s": "Kon de geplakte tekst niet aanmaken: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de geplakte tekst niet decoderen: Decoderingssleutel ontbreekt in URL (Hebt u een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de geplakte tekst niet decoderen: Decoderingssleutel ontbreekt in URL (Hebt u een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)",
"B": "B",
"KiB": "KiB",
"MiB": "MiB",
@@ -164,26 +164,30 @@
"Preparing new paste…": "Nieuwe geplakte tekst voorbereiden…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In het geval dat dit bericht nooit verdwijnt, kijkt u dan eens naar <a href=\"%s\"> veelgestelde vragen voor informatie over het oplossen van problemen </a>.",
"+++ no paste text +++": "+++ geen geplakte tekst +++",
"Could not get paste data: %s": "Could not get paste data: %s",
"QR code": "QR code",
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
"waiting on user to provide a password": "waiting on user to provide a password",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
"Retry": "Retry",
"Showing raw text…": "Showing raw text…",
"Notice:": "Notice:",
"This link will expire after %s.": "This link will expire after %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
"Could not get paste data: %s": "Kon geen klembordgegevens verkrijgen: %s",
"QR code": "QR-code",
"This website is using an insecure HTTP connection! Please use it only for testing.": "Deze website gebruikt een onveilige HTTP-verbinding! Gelieve deze enkel te gebruiken om te testen.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Voor meer informatie <a href=\"%s\">zie dit FAQ-artikel</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Uw browser kan een HTTPS-verbinding nodig hebben om de WebCrypto API te ondersteunen. Probeer <a href=\"%s\">het met HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Uw browser ondersteunt WebAssembly niet, wat wordt gebruikt voor zlib compressie. U kunt niet-gecomprimeerde documenten maken, maar geen gecomprimeerde documenten lezen.",
"waiting on user to provide a password": "wachtend op gebruiker om een wachtwoord te geven",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Kon de gegevens niet decoderen. Heeft u een verkeerd wachtwoord ingevoerd? Probeer het opnieuw met de knop bovenaan.",
"Retry": "Opnieuw proberen",
"Showing raw text…": "Platte tekst tonen…",
"Notice:": "Let op:",
"This link will expire after %s.": "Deze link vervalt na %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Deze link kan slechts eenmaal worden geopend, gebruik niet de terug- of verversknop in uw browser.",
"Link:": "Link:",
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Recipient may become aware of your timezone, convert time to UTC?": "Ontvanger kan zich bewust worden van uw tijdzone, tijd omzetten naar UTC?",
"Use Current Timezone": "Gebruik huidige tijdzone",
"Convert To UTC": "Omzetten naar UTC",
"Close": "Sluiten",
"Encrypted note on %s": "Versleutelde notitie op %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Bezoek deze link om de notitie te bekijken. Als je de URL aan iemand geeft, kan die de notitie ook bekijken.",
"URL shortener may expose your decrypt key in URL.": "URL-verkorter kan uw ontcijferingssleutel in URL blootleggen.",
"Save paste": "Notitie opslaan",
"Your IP is not authorized to create pastes.": "Uw IP-adres is niet gemachtigd om geplakte tekst te maken.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Bruk gjeldende tidssone",
"Convert To UTC": "Konverter til UTC",
"Close": "Steng",
"Encrypted note on PrivateBin": "Kryptert notat på PrivateBin",
"Encrypted note on %s": "Kryptert notat på %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Besøk denne lenken for å se notatet. Hvis lenken deles med andre, vil de også kunne se notatet.",
"URL shortener may expose your decrypt key in URL.": "URL forkorter kan avsløre dekrypteringsnøkkelen.",
"Save paste": "Lagre utklipp"
"Save paste": "Lagre utklipp",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -37,76 +37,76 @@
"%d seconds": [
"%d segonda",
"%d segondas",
"%d seconds (2nd plural)",
"%d seconds (3rd plural)"
"%d segondas",
"%d segondas"
],
"%d minutes": [
"%d minuta",
"%d minutas",
"%d minutes (2nd plural)",
"%d minutes (3rd plural)"
"%d minutas",
"%d minutas"
],
"%d hours": [
"%d ora",
"%d oras",
"%d hours (2nd plural)",
"%d hours (3rd plural)"
"%d oras",
"%d oras"
],
"%d days": [
"%d jorn",
"%d jorns",
"%d days (2nd plural)",
"%d days (3rd plural)"
"%d jorns",
"%d jorns"
],
"%d weeks": [
"%d setmana",
"%d setmanas",
"%d weeks (2nd plural)",
"%d weeks (3rd plural)"
"%d setmanas",
"%d setmanas"
],
"%d months": [
"%d mes",
"%d meses",
"%d months (2nd plural)",
"%d months (3rd plural)"
"%d meses",
"%d meses"
],
"%d years": [
"%d an",
"%d ans",
"%d years (2nd plural)",
"%d years (3rd plural)"
"%d ans",
"%d ans"
],
"Never": "Jamai",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Nota:Aquò es un servici despròva:las donadas pòdon èsser suprimidas a cada moment. De catons moriràn sabusatz daqueste servici.",
"This document will expire in %d seconds.": [
"Ce document expirera dans %d seconde.",
"Aqueste document expirarà dins %d segondas.",
"Aqueste document expirarà dins %d segondas.",
"Aqueste document expirarà dins %d segondas."
"Aqueste document expirarà daquí %d segonda.",
"Aqueste document expirarà daquí %d segondas.",
"Aqueste document expirarà daquí %d segondas.",
"Aqueste document expirarà daquí %d segondas."
],
"This document will expire in %d minutes.": [
"Ce document expirera dans %d minute.",
"Aqueste document expirarà dins %d minutas.",
"Aqueste document expirarà dins %d minutas.",
"Aqueste document expirarà dins %d minutas."
"Aqueste document expirarà daquí %d minuta.",
"Aqueste document expirarà daquí %d minutas.",
"Aqueste document expirarà daquí %d minutas.",
"Aqueste document expirarà daquí %d minutas."
],
"This document will expire in %d hours.": [
"Ce document expirera dans %d heure.",
"Aqueste document expirarà dins %d oras.",
"Aqueste document expirarà dins %d oras.",
"Aqueste document expirarà dins %d oras."
"Aqueste document expirarà daquí %d ora.",
"Aqueste document expirarà daquí %d oras.",
"Aqueste document expirarà daquí %d oras.",
"Aqueste document expirarà daquí %d oras."
],
"This document will expire in %d days.": [
"Ce document expirera dans %d jour.",
"Aqueste document expirarà dins %d jorns.",
"Aqueste document expirarà dins %d jorns.",
"Aqueste document expirarà dins %d jorns."
"Aqueste document expirarà daquí %d jorn.",
"Aqueste document expirarà daquí %d jorns.",
"Aqueste document expirarà daquí %d jorns.",
"Aqueste document expirarà daquí %d jorns."
],
"This document will expire in %d months.": [
"Ce document expirera dans %d mois.",
"Aqueste document expirarà dins %d meses.",
"Aqueste document expirarà dins %d meses.",
"Aqueste document expirarà dins %d meses."
"Aqueste document expirarà daquí %d mes.",
"Aqueste document expirarà daquí %d meses.",
"Aqueste document expirarà daquí %d meses.",
"Aqueste document expirarà daquí %d meses."
],
"Please enter the password for this paste:": "Picatz lo senhal per aqueste tèxte:",
"Could not decrypt data (Wrong key?)": "Impossible de deschifrar las donadas (marrida clau?)",
@@ -156,7 +156,7 @@
"Shorten URL": "Acorchir lURL",
"Editor": "Editar",
"Preview": "Previsualizar",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s demanda que lo PATH termine en \"%s\". Mercés de metre a jorn lo PATH dins vòstre index.php.",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s demanda que lo PATH termine en « %s». Mercés de metre a jorn lo PATH dins vòstre index.php.",
"Decrypt": "Deschifrar",
"Enter password": "Picatz lo senhal",
"Loading…": "Cargament…",
@@ -182,8 +182,12 @@
"Use Current Timezone": "Utilizar lactual",
"Convert To UTC": "Convertir en UTC",
"Close": "Tampar",
"Encrypted note on PrivateBin": "Nòtas chifradas sus PrivateBin",
"Encrypted note on %s": "Nòtas chifradas sus %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visitatz aqueste ligam per veire la nòta. Fornir lo ligam a qualquun mai li permet tanben daccedir a la nòta.",
"URL shortener may expose your decrypt key in URL.": "Los espleches dacorchiment dURL pòdon expausar la clau de deschiframent dins lURL.",
"Save paste": "Enregistrar lo tèxt"
"Save paste": "Enregistrar lo tèxt",
"Your IP is not authorized to create pastes.": "Vòstra adreça IP a pas lautorizacion de crear de tèxtes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Usar Fuso Horário Atual",
"Convert To UTC": "Converter para UTC",
"Close": "Fechar",
"Encrypted note on PrivateBin": "Nota criptografada no PrivateBin",
"Encrypted note on %s": "Nota criptografada no %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visite esse link para ver a nota. Dar a URL para qualquer um permite que eles também acessem a nota.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Использовать текущий часовой пояс",
"Convert To UTC": "Конвертировать в UTC",
"Close": "Закрыть",
"Encrypted note on PrivateBin": "Зашифрованная запись на PrivateBin",
"Encrypted note on %s": "Зашифрованная запись на %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Посетите эту ссылку чтобы просмотреть запись. Передача ссылки кому либо позволит им получить доступ к записи тоже.",
"URL shortener may expose your decrypt key in URL.": "Сервис сокращения ссылок может получить ваш ключ расшифровки из ссылки.",
"Save paste": "Сохранить запись"
"Save paste": "Сохранить запись",
"Your IP is not authorized to create pastes.": "Вашему IP адресу не разрешено создавать записи.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

193
i18n/sk.json Normal file
View File

@@ -0,0 +1,193 @@
{
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s je minimalistický, open source online pastebin, kde server nemá žiadne znalosti o vložených údajoch. Údaje sú šifrované/dešifrované %sv prehliadači%s pomocou 256-bitového AES.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Viac informácií na <a href=\"https://privatebin.info/\">stránke projektu</a>.",
"Because ignorance is bliss": "Pretože nevedomosť je sladká",
"en": "sk",
"Paste does not exist, has expired or has been deleted.": "Vložený text neexistuje, jeho platnosť vypršala alebo bol vymazaný.",
"%s requires php %s or above to work. Sorry.": "%s vyžaduje php %s alebo vyššie. Prepáčte.",
"%s requires configuration section [%s] to be present in configuration file.": "%s vyžaduje, aby bola v konfiguračnom súbore prítomná sekcia [%s].",
"Please wait %d seconds between each post.": [
"Počet sekúnd do ďalšieho príspevku: %d",
"Počet sekúnd do ďalšieho príspevku: %d",
"Počet sekúnd do ďalšieho príspevku: %d",
"Počet sekúnd do ďalšieho príspevku: %d"
],
"Paste is limited to %s of encrypted data.": "Príspevok je obmedzený na %s zašifrovaných údajov.",
"Invalid data.": "Neplatné údaje.",
"You are unlucky. Try again.": "Ľutujem. Skúste to znova.",
"Error saving comment. Sorry.": "Pri ukladaní komentára sa vyskytla chyba.",
"Error saving paste. Sorry.": "Pri ukladaní príspevku sa vyskytla chyba.",
"Invalid paste ID.": "Chybne vložené ID.",
"Paste is not of burn-after-reading type.": "Príspevok nieje nastavený na zmazanie po prečítaní.",
"Wrong deletion token. Paste was not deleted.": "Nesprávny token odstránenia. Príspevok nebol odstránený.",
"Paste was properly deleted.": "Príspevok bol správne vymazaný.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "Na fungovanie %s je potrebný JavaScript. Ospravedlňujeme sa za nepríjemnosti.",
"%s requires a modern browser to work.": "%s vyžaduje na fungovanie moderný prehliadač.",
"New": "Nový",
"Send": "Odoslať",
"Clone": "Klonovať",
"Raw text": "Surový text",
"Expires": "Expirácia",
"Burn after reading": "Po prečítaní zmazať",
"Open discussion": "Povoliť komentáre",
"Password (recommended)": "Heslo (doporučené)",
"Discussion": "Komentáre",
"Toggle navigation": "Prepnúť navigáciu",
"%d seconds": [
"%d sekunda",
"%d sekundy",
"%d sekúnd",
"%d sekúnd"
],
"%d minutes": [
"%d minúta",
"%d minúty",
"%d minút",
"%d minút"
],
"%d hours": [
"%d hodina",
"%d hodiny",
"%d hodín",
"%d hodín"
],
"%d days": [
"%d deň",
"%d dni",
"%d dní",
"%d dní"
],
"%d weeks": [
"%d týždeň",
"%d týždne",
"%d týždňov",
"%d týždňov"
],
"%d months": [
"%d mesiac",
"%d mesiace",
"%d mesiacov",
"%d mesiacov"
],
"%d years": [
"%d rok",
"%d roky",
"%d rokov",
"%d rokov"
],
"Never": "Nikdy",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Poznámka: Toto je testovacia služba: Údaje môžu byť kedykoľvek vymazané. Pri zneužití tejto služby zomrú mačiatka.",
"This document will expire in %d seconds.": [
"Platnosť tohto dokumentu vyprší o %d sekundu.",
"Platnosť tohto dokumentu vyprší o %d sekundy.",
"Platnosť tohto dokumentu vyprší o %d sekúnd.",
"Platnosť tohto dokumentu vyprší o %d sekúnd."
],
"This document will expire in %d minutes.": [
"Platnosť tohto dokumentu vyprší o %d minútu.",
"Platnosť tohto dokumentu vyprší o %d minúty.",
"Platnosť tohto dokumentu vyprší o %d minút.",
"Platnosť tohto dokumentu vyprší o %d minút."
],
"This document will expire in %d hours.": [
"Platnosť tohto dokumentu vyprší o %d hodinu.",
"Platnosť tohto dokumentu vyprší o %d hodiny.",
"Platnosť tohto dokumentu vyprší o %d hodín.",
"Platnosť tohto dokumentu vyprší o %d hodín."
],
"This document will expire in %d days.": [
"Platnosť tohto dokumentu vyprší o %d deň.",
"Platnosť tohto dokumentu vyprší o %d dni.",
"Platnosť tohto dokumentu vyprší o %d dní.",
"Platnosť tohto dokumentu vyprší o %d dní."
],
"This document will expire in %d months.": [
"Platnosť tohto dokumentu vyprší o %d mesiac.",
"Platnosť tohto dokumentu vyprší o %d mesiace.",
"Platnosť tohto dokumentu vyprší o %d mesiacov.",
"Platnosť tohto dokumentu vyprší o %d mesiacov."
],
"Please enter the password for this paste:": "Zadajte prosím heslo:",
"Could not decrypt data (Wrong key?)": "Nepodarilo sa dešifrovať údaje (nesprávny kľúč?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Nepodarilo sa odstrániť príspevok, nebol uložený v režime zmazania po prečítaní.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "IBA PRE VAŠE OČI. Toto okno nezatvárajte, táto správa sa nedá znova zobraziť.",
"Could not decrypt comment; Wrong key?": "Nepodarilo sa dešifrovať komentár. Nesprávny kľúč?",
"Reply": "Odpovedať",
"Anonymous": "Anonymný",
"Avatar generated from IP address": "Avatar vygenerovaný z IP adresy",
"Add comment": "Pridať komentár",
"Optional nickname…": "Voliteľná prezývka…",
"Post comment": "Odoslať komentár",
"Sending comment…": "Odosielanie komentára…",
"Comment posted.": "Komentár odoslaný.",
"Could not refresh display: %s": "Nepodarilo sa obnoviť zobrazenie: %s",
"unknown status": "neznámy stav",
"server error or not responding": "chyba servera alebo server neodpovedá",
"Could not post comment: %s": "Nepodarilo sa pridať komentár: %s",
"Sending paste…": "Odosiela sa príspevok…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Váš príspevok je <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(skopírujte stlačením [Ctrl]+[c])</span>",
"Delete data": "Odstrániť dáta",
"Could not create paste: %s": "Nepodarilo sa vytvoriť príspevok: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Nie je možné dešifrovať príspevok: V URL adrese chýba dešifrovací kľúč (Použili ste presmerovač alebo skracovač adresy, ktorý odstráni časť adresy URL?)",
"B": "B",
"KiB": "KiB",
"MiB": "MiB",
"GiB": "GiB",
"TiB": "TiB",
"PiB": "PiB",
"EiB": "EiB",
"ZiB": "ZiB",
"YiB": "YiB",
"Format": "Formát",
"Plain Text": "Čistý text",
"Source Code": "Zdrojový kód",
"Markdown": "Markdown",
"Download attachment": "Stiahnuť prílohu",
"Cloned: '%s'": "Naklonované: '%s'",
"The cloned file '%s' was attached to this paste.": "K tomuto príspevku bol pripojený klonovaný súbor '%s'.",
"Attach a file": "Priložiť súbor",
"alternatively drag & drop a file or paste an image from the clipboard": "prípadne presuňte súbor myšou alebo vložte obrázok zo schránky",
"File too large, to display a preview. Please download the attachment.": "Súbor je príliš veľký na zobrazenie ukážky. Stiahnite si prosím prílohu.",
"Remove attachment": "Odstrániť prílohu",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Váš prehliadač nepodporuje nahrávanie šifrovaných súborov. Použite prosím novší prehliadač.",
"Invalid attachment.": "Neplatná príloha.",
"Options": "Možnosti",
"Shorten URL": "Skrátiť URL",
"Editor": "Editor",
"Preview": "Náhľad",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vyžaduje, aby PATH končila na \"%s\". Aktualizujte prosím PATH vo svojom index.php.",
"Decrypt": "Dešifrovať",
"Enter password": "Zadajte heslo",
"Loading…": "Načítava sa…",
"Decrypting paste…": "Dešifrovanie príspevku…",
"Preparing new paste…": "Príprava nového príspevku…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "V prípade, že táto správa nezmizne, pozrite si <a href=\"%s\">tieto často kladené otázky, kde nájdete informácie na riešenie problémov</a>.",
"+++ no paste text +++": "+++ žiadny vložený text +++",
"Could not get paste data: %s": "Nepodarilo sa načítať údaje príspevku: %s",
"QR code": "QR kód",
"This website is using an insecure HTTP connection! Please use it only for testing.": "Táto webová stránka používa nezabezpečené pripojenie HTTP! Používajte ju len na testovanie.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Pre viac informácií si pozrite <a href=\"%s\">tento záznam FAQ</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Váš prehliadač môže na podporu rozhrania WebCrypto API vyžadovať pripojenie HTTPS. Skúste <a href=\"%s\">prepnúť na HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Váš prehliadač nepodporuje WebAssembly, ktorý sa používa na kompresiu zlib. Môžete vytvárať nekomprimované dokumenty, ale nemôžete čítať komprimované.",
"waiting on user to provide a password": "čakám na zadanie hesla",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Údaje sa nepodarilo dešifrovať. Zadali ste nesprávne heslo? Skúste to znova pomocou tlačidla v hornej časti.",
"Retry": "Opakovať",
"Showing raw text…": "Zobrazuje sa surový text…",
"Notice:": "Upozornenie:",
"This link will expire after %s.": "Platnosť odkazu vyprší za %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Tento odkaz je prístupný iba raz, nepoužívajte v prehliadači tlačidlo Späť ani Obnoviť.",
"Link:": "Odkaz:",
"Recipient may become aware of your timezone, convert time to UTC?": "Príjemca sa môže dozvedieť o vašom časovom pásme, previesť čas na UTC?",
"Use Current Timezone": "Použiť aktuálne časové pásmo",
"Convert To UTC": "Previesť na UTC",
"Close": "Zavrieť",
"Encrypted note on %s": "Zašifrovaná poznámka na %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Ak chcete zobraziť poznámku, navštívte tento odkaz. Poskytnutie adresy URL komukoľvek im umožní prístup aj k poznámke.",
"URL shortener may expose your decrypt key in URL.": "Skracovač adries URL môže odhaliť váš dešifrovací kľúč v adrese URL.",
"Save paste": "Uložiť príspevok",
"Your IP is not authorized to create pastes.": "Vaša IP adresa nie je oprávnená vytvárať príspevky.",
"Trying to shorten a URL that isn't pointing at our instance.": "Pokúšate sa skrátiť adresu URL, ktorá neukazuje na túto inštanciu.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Encrypted note on %s": "Encrypted note on %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Save paste": "Save paste",
"Your IP is not authorized to create pastes.": "Your IP is not authorized to create pastes.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -1,135 +1,135 @@
{
"PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s sunucunun burada paylaştığınız veriyi görmediği, minimal, açık kaynak bir pastebindir. Veriler tarayıcıda 256 bit AES kullanılarak şifrelenir/çözülür.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Daha fazla bilgi için <a href=\"https://privatebin.info/\">proje sayfası</a>'na göz atabilirsiniz.",
"Because ignorance is bliss": "Çünkü, cehalet mutluluktur",
"en": "tr",
"Paste does not exist, has expired or has been deleted.": "Paste does not exist, has expired or has been deleted.",
"%s requires php %s or above to work. Sorry.": "%s requires php %s or above to work. Sorry.",
"%s requires configuration section [%s] to be present in configuration file.": "%s requires configuration section [%s] to be present in configuration file.",
"%s requires php %s or above to work. Sorry.": "%s PHP %s veya daha üstünü gerektirir.",
"%s requires configuration section [%s] to be present in configuration file.": "%s konfigürasyon bölümünün [%s] bulunmasını gerektir.",
"Please wait %d seconds between each post.": [
"Please wait %d second between each post. (singular)",
"Please wait %d seconds between each post. (1st plural)",
"Please wait %d seconds between each post. (2nd plural)",
"Please wait %d seconds between each post. (3rd plural)"
"Lütfen paylaşımlar arasında %d saniye bekleyiniz.",
"Lütfen paylaşımlar arasında %d saniye bekleyiniz.",
"Lütfen paylaşımlar arasında %d saniye bekleyiniz.",
"Lütfen paylaşımlar arasında %d saniye bekleyiniz."
],
"Paste is limited to %s of encrypted data.": "Paste is limited to %s of encrypted data.",
"Paste is limited to %s of encrypted data.": "Yazılar %s şifreli veriyle sınırlıdır.",
"Invalid data.": "Geçersiz veri.",
"You are unlucky. Try again.": "Lütfen tekrar deneyiniz.",
"Error saving comment. Sorry.": "Error saving comment. Sorry.",
"Error saving paste. Sorry.": "Error saving paste. Sorry.",
"Invalid paste ID.": "Invalid paste ID.",
"Paste is not of burn-after-reading type.": "Paste is not of burn-after-reading type.",
"Wrong deletion token. Paste was not deleted.": "Wrong deletion token. Paste was not deleted.",
"Paste was properly deleted.": "Paste was properly deleted.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript is required for %s to work. Sorry for the inconvenience.",
"%s requires a modern browser to work.": "%s requires a modern browser to work.",
"Error saving comment. Sorry.": "Yorum kaydedilemedi.",
"Error saving paste. Sorry.": "Yazı kaydedilemedi. Üzgünüz.",
"Invalid paste ID.": "Geçersiz yazı ID'si.",
"Paste is not of burn-after-reading type.": "Yazı okunduğunda silinmeyecek şekilde ayarlanmış.",
"Wrong deletion token. Paste was not deleted.": "Yanlış silme anahtarı. Yazı silinemedi.",
"Paste was properly deleted.": "Yazı başarıyla silindi.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript %s 'in çalışması için gereklidir. Rahatsızlıktan dolayı özür dileriz.",
"%s requires a modern browser to work.": "%s çalışmak için çağdaş bir tarayıcı gerektirir.",
"New": "Yeni",
"Send": "Gönder",
"Clone": "Kopyala",
"Raw text": "Raw text",
"Raw text": "ık yazı",
"Expires": "Süre Sonu",
"Burn after reading": "Burn after reading",
"Burn after reading": "Okuduktan sonra sil",
"Open discussion": "Açık Tartışmalar",
"Password (recommended)": "Password (recommended)",
"Password (recommended)": "Şifre (önerilir)",
"Discussion": "Tartışma",
"Toggle navigation": "Gezinmeyi değiştir",
"%d seconds": [
"%d second (singular)",
"%d seconds (1st plural)",
"%d seconds (2nd plural)",
"%d seconds (3rd plural)"
"%d saniye",
"%d saniye",
"%d saniye",
"%d saniye"
],
"%d minutes": [
"%d minute (singular)",
"%d minutes (1st plural)",
"%d minutes (2nd plural)",
"%d minutes (3rd plural)"
"%d dakika",
"%d dakika",
"%d dakika",
"%d dakika"
],
"%d hours": [
"%d hour (singular)",
"%d hours (1st plural)",
"%d hours (2nd plural)",
"%d hours (3rd plural)"
"%d saat",
"%d saat",
"%d saat",
"%d saat"
],
"%d days": [
"%d day (singular)",
"%d days (1st plural)",
"%d days (2nd plural)",
"%d days (3rd plural)"
"%d gün",
"%d gün",
"%d gün",
"%d gün"
],
"%d weeks": [
"%d hafta (tekil)",
"%d haftalar (çoğul)",
"%d weeks (2nd plural)",
"%d weeks (3rd plural)"
"%d hafta",
"%d haftalar",
"%d hafta",
"%d hafta"
],
"%d months": [
"%d month (singular)",
"%d months (1st plural)",
"%d months (2nd plural)",
"%d months (3rd plural)"
"%d ay",
"%d ay",
"%d ay",
"%d ay"
],
"%d years": [
"%d year (singular)",
"%d years (1st plural)",
"%d years (2nd plural)",
"%d years (3rd plural)"
"%d yıl",
"%d yıl",
"%d yıl",
"%d yıl"
],
"Never": "Never",
"Never": "Asla",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
"This document will expire in %d seconds.": [
"This document will expire in %d second. (singular)",
"This document will expire in %d seconds. (1st plural)",
"This document will expire in %d seconds. (2nd plural)",
"This document will expire in %d seconds. (3rd plural)"
"Bu belge %d saniyede silinecektir.",
"Bu belge %d saniyede silinecektir.",
"Bu belge %d saniyede silinecektir.",
"Bu belge %d saniyede silinecektir."
],
"This document will expire in %d minutes.": [
"This document will expire in %d minute. (singular)",
"This document will expire in %d minutes. (1st plural)",
"This document will expire in %d minutes. (2nd plural)",
"This document will expire in %d minutes. (3rd plural)"
"Bu belge %d dakikada silinecektir.",
"Bu belge %d dakikada silinecektir.",
"Bu belge %d dakikada silinecektir.",
"Bu belge %d dakikada silinecektir."
],
"This document will expire in %d hours.": [
"This document will expire in %d hour. (singular)",
"This document will expire in %d hours. (1st plural)",
"This document will expire in %d hours. (2nd plural)",
"This document will expire in %d hours. (3rd plural)"
"Bu belge %d saatte silinecektir.",
"Bu belge %d saatte silinecektir.",
"Bu belge %d saatte silinecektir.",
"Bu belge %d saatte silinecektir."
],
"This document will expire in %d days.": [
"This document will expire in %d day. (singular)",
"This document will expire in %d days. (1st plural)",
"This document will expire in %d days. (2nd plural)",
"This document will expire in %d days. (3rd plural)"
"Bu belge %d günde silinecektir.",
"Bu belge %d günde silinecektir.",
"Bu belge %d günde silinecektir.",
"Bu belge %d günde silinecektir."
],
"This document will expire in %d months.": [
"This document will expire in %d month. (singular)",
"This document will expire in %d months. (1st plural)",
"This document will expire in %d months. (2nd plural)",
"This document will expire in %d months. (3rd plural)"
"Bu belge %d ayda silinecektir.",
"Bu belge %d ayda silinecektir.",
"Bu belge %d ayda silinecektir.",
"Bu belge %d ayda silinecektir."
],
"Please enter the password for this paste:": "Please enter the password for this paste:",
"Could not decrypt data (Wrong key?)": "Could not decrypt data (Wrong key?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
"Please enter the password for this paste:": "Lütfen bu yazı için şifrenizi girin:",
"Could not decrypt data (Wrong key?)": "Şifre çözülemedi (Yanlış anahtar mı kullandınız?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Yazı silinemedi, okunduktan sonra silinmek için ayarlanmadı.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "BU DOSYAYI SADECE SİZ GÖRÜNTÜLEYEBİLİRSİNİZ. Bu pencereyi kapatmayın, yazıyı tekrar görüntüleyemeyeceksiniz.",
"Could not decrypt comment; Wrong key?": "Dosya şifresi çözülemedi, doğru anahtarı girdiğinizden emin misiniz?",
"Reply": "Cevapla",
"Anonymous": "Anonim",
"Avatar generated from IP address": "Avatar generated from IP address",
"Avatar generated from IP address": "IP adresinden oluşturulmuş avatar",
"Add comment": "Yorum ekle",
"Optional nickname…": "Optional nickname…",
"Optional nickname…": "İsteğe bağlı takma isim…",
"Post comment": "Yorumu gönder",
"Sending comment…": "Sending comment…",
"Sending comment…": "Yorum gönderiliyor…",
"Comment posted.": "Yorum gönderildi.",
"Could not refresh display: %s": "Could not refresh display: %s",
"unknown status": "unknown status",
"server error or not responding": "server error or not responding",
"Could not post comment: %s": "Could not post comment: %s",
"Sending paste…": "Sending paste…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
"Could not refresh display: %s": "Görüntü yenilenemedi: %s",
"unknown status": "bilinmeyen durum",
"server error or not responding": "sunucu hatası veya yanıt vermiyor",
"Could not post comment: %s": "Yorum paylaşılamadı: %s",
"Sending paste…": "Yazı gönderiliyor…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Yazınız: <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">([Ctrl]+[c] tuşlarına basarak kopyalayın.)</span>",
"Delete data": "Veriyi sil",
"Could not create paste: %s": "Could not create paste: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
"Could not create paste: %s": "Yazı oluşturulamadı: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Yazı şifresi çözülemedi, çözme anahtarı URL'de bulunamadı. (Buraya bir yönlendirici veya URL kısaltıcı kullanarak gelmiş olabilirsiniz.)",
"B": "B",
"KiB": "KiB",
"MiB": "MiB",
@@ -140,50 +140,54 @@
"ZiB": "ZiB",
"YiB": "YiB",
"Format": "Format",
"Plain Text": "Plain Text",
"Source Code": "Source Code",
"Plain Text": "Düz Yazı",
"Source Code": "Kaynak Kodu",
"Markdown": "Markdown",
"Download attachment": "Download attachment",
"Cloned: '%s'": "Cloned: '%s'",
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
"Attach a file": "Attach a file",
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
"File too large, to display a preview. Please download the attachment.": "File too large, to display a preview. Please download the attachment.",
"Remove attachment": "Remove attachment",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Your browser does not support uploading encrypted files. Please use a newer browser.",
"Invalid attachment.": "Invalid attachment.",
"Options": "Options",
"Shorten URL": "Shorten URL",
"Editor": "Editor",
"Download attachment": "Eki indir",
"Cloned: '%s'": "Klonlandı: '%s'",
"The cloned file '%s' was attached to this paste.": "Klonlanmış dosya '%s' bu yazıya eklendi.",
"Attach a file": "Dosya ekle",
"alternatively drag & drop a file or paste an image from the clipboard": "alternatif olarak dosyasyı yapıştırabilir veya sürükleyip bırakabilirsin",
"File too large, to display a preview. Please download the attachment.": "Dosya önizleme için çok büyük. Lütfen eki indirin.",
"Remove attachment": "Eki sil",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Tarayıcınız şifreli dosyaları desteklemiyor.",
"Invalid attachment.": "Geçersiz ek.",
"Options": "Seçenekler",
"Shorten URL": "URL kısaltma",
"Editor": "Düzenleyici",
"Preview": "Ön izleme",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
"Decrypt": "Decrypt",
"Decrypt": "Şifreyi çöz",
"Enter password": "Şifreyi girin",
"Loading…": "Yükleniyor…",
"Decrypting paste…": "Decrypting paste…",
"Preparing new paste…": "Preparing new paste…",
"Decrypting paste…": "Yazı şifresi çözülüyor…",
"Preparing new paste…": "Yeni yazı hazırlanıyor…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
"+++ no paste text +++": "+++ no paste text +++",
"Could not get paste data: %s": "Could not get paste data: %s",
"Could not get paste data: %s": "Yazı verisi alınamıyor: %s",
"QR code": "QR kodu",
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
"waiting on user to provide a password": "waiting on user to provide a password",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Dosya şifresi çözülemedi, doğru şifreyi kullandığınıza emin misiniz? Üstteki buton ile tekrar deneyin.",
"Retry": "Yeniden Dene",
"Showing raw text…": "Showing raw text…",
"Showing raw text…": "ık yazı gösteriliyor…",
"Notice:": "Bildirim:",
"This link will expire after %s.": "This link will expire after %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
"This link will expire after %s.": "Bu bağlantı şu kadar zaman sonra etkisiz kalacaktır: %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Bu bağlantı sadece bir kere erişilebilir, lütfen sayfayı yenilemeyiniz.",
"Link:": "Bağlantı:",
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Recipient may become aware of your timezone, convert time to UTC?": "Alıcı zaman dilmini öğrenebilir, zaman dilimini UTC'ye çevirmek ister misin?",
"Use Current Timezone": "Şuanki zaman dilimini kullan",
"Convert To UTC": "UTC zaman dilimine çevir",
"Close": "Kapat",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"Encrypted note on %s": "%s üzerinde şifrelenmiş not",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Notu görmek için bu bağlantıyı ziyaret et. Bağlantıya sahip olan birisi notu görebilir.",
"URL shortener may expose your decrypt key in URL.": "URL kısaltıcı şifreleme anahtarınızı URL içerisinde gösterebilir.",
"Save paste": "Yazıyı kaydet",
"Your IP is not authorized to create pastes.": "IP adresinizin yazı oluşturmaya yetkisi yoktur.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -8,10 +8,10 @@
"%s requires php %s or above to work. Sorry.": "Для роботи %s потрібен php %s и вище. Вибачте.",
"%s requires configuration section [%s] to be present in configuration file.": "%s потрібна секція [%s] в конфігураційному файлі.",
"Please wait %d seconds between each post.": [
"Please wait %d second between each post. (singular)",
"Please wait %d seconds between each post. (1st plural)",
"Please wait %d seconds between each post. (2nd plural)",
"Please wait %d seconds between each post. (3rd plural)"
"Будь ласка, зачекайте %d секунду між створеннями.",
"Будь ласка, зачекайте %d секунди між створеннями.",
"Будь ласка, зачекайте %d секунд між створеннями.",
"Будь ласка, зачекайте %d секунд між створеннями."
],
"Paste is limited to %s of encrypted data.": "Розмір допису обмежений %s зашифрованих даних.",
"Invalid data.": "Неправильні дані.",
@@ -170,20 +170,24 @@
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Для подробиць <a href=\"%s\">дивіться інформацію в FAQ</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Ваш переглядач вимагає підключення HTTPS для підтримки WebCrypto API. Спробуйте <a href=\"%s\">перемкнутися на HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Ваш переглядач не підтримує WebAssembly, що використовується для стиснення zlib. Ви можете створювати нестиснені документи, але не зможете читати стиснені.",
"waiting on user to provide a password": "waiting on user to provide a password",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
"Retry": "Retry",
"Showing raw text…": "Showing raw text…",
"Notice:": "Notice:",
"This link will expire after %s.": "This link will expire after %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
"Link:": "Link:",
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
"Use Current Timezone": "Use Current Timezone",
"Convert To UTC": "Convert To UTC",
"Close": "Close",
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
"Save paste": "Save paste"
"waiting on user to provide a password": "очікування користувача для вводу паролю",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Не вдалося розшифрувати дані. Може, ви ввели неправильний пароль? Спробуйте знову за допомогою верхньої кнопки.",
"Retry": "Спробуйте ще раз",
"Showing raw text…": "Відображається неформатований текст…",
"Notice:": "Зверніть увагу:",
"This link will expire after %s.": "Термін дії цього посилання сплине через %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Дане посилання доступна тільки один раз, не натискайте кнопку назад та не обновляйте сторінку браузера.",
"Link:": "Посилання:",
"Recipient may become aware of your timezone, convert time to UTC?": "Отримувач дізнається ваш часовий пояс, перетворити час в UTC?",
"Use Current Timezone": "Використовувати поточний часовий пояс",
"Convert To UTC": "Конвертувати в UTC",
"Close": "Закрити",
"Encrypted note on %s": "Зашифрована нотатка на %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Відвідайте посилання, щоб переглянути нотатку. Передача посилання будь-кому дозволить їм переглянути нотатку.",
"URL shortener may expose your decrypt key in URL.": "Сервіс скорочення посилань може викрити ваш ключ дешифрування з URL.",
"Save paste": "Зберегти вставку",
"Your IP is not authorized to create pastes.": "Вашому IP не дозволено створювати вставки.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -182,8 +182,12 @@
"Use Current Timezone": "使用当前时区",
"Convert To UTC": "转换为 UTC",
"Close": "关闭",
"Encrypted note on PrivateBin": "PrivateBin 上的加密笔记",
"Encrypted note on %s": "%s 上的加密笔记",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "访问此链接来查看该笔记。将此 URL 发送给任何人即可允许其访问该笔记。",
"URL shortener may expose your decrypt key in URL.": "短链接服务可能会暴露您在 URL 中的解密密钥。",
"Save paste": "保存内容"
"Save paste": "保存内容",
"Your IP is not authorized to create pastes.": "您的 IP 无权创建粘贴。",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response."
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
// change this, if your php files and data is outside of your webservers document root

File diff suppressed because one or more lines are too long

6
js/bootstrap-3.4.1.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -12,15 +12,15 @@ global.WebCrypto = require('@peculiar/webcrypto').Crypto;
// application libraries to test
global.$ = global.jQuery = require('./jquery-3.6.0');
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
global.zlib = require('./zlib-1.2.11').zlib;
global.zlib = require('./zlib-1.2.13').zlib;
require('./prettify');
global.prettyPrint = window.PR.prettyPrint;
global.prettyPrintOne = window.PR.prettyPrintOne;
global.showdown = require('./showdown-2.0.0');
global.showdown = require('./showdown-2.0.3');
global.DOMPurify = require('./purify-2.3.6');
global.baseX = require('./base-x-4.0.0').baseX;
global.Legacy = require('./legacy').Legacy;
require('./bootstrap-3.3.7');
require('./bootstrap-3.4.1');
require('./privatebin');
// internal variables
@@ -131,4 +131,3 @@ exports.jscMimeTypes = function() {
exports.jscFormats = function() {
return jsc.elements(formats);
};

1785
js/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "privatebin",
"version": "1.3.5",
"version": "1.4.0",
"description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).",
"main": "privatebin.js",
"directories": {

View File

@@ -6,7 +6,7 @@
* @see {@link https://github.com/PrivateBin/PrivateBin}
* @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net})
* @license {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License}
* @version 1.3.5
* @version 1.4.0
* @name PrivateBin
* @namespace
*/
@@ -52,6 +52,31 @@ jQuery.PrivateBin = (function($, RawDeflate) {
*/
let z;
/**
* DOMpurify settings for HTML content
*
* @private
*/
const purifyHtmlConfig = {
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
SAFE_FOR_JQUERY: true,
USE_PROFILES: {
html: true
}
};
/**
* DOMpurify settings for SVG content
*
* @private
*/
const purifySvgConfig = {
USE_PROFILES: {
svg: true,
svgFilters: true
}
};
/**
* CryptoData class
*
@@ -409,7 +434,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
element.html().replace(
/(((https?|ftp):\/\/[\w?!=&.\/-;#@~%+*-]+(?![\w\s?!&.\/;#~%"=-]>))|((magnet):[\w?=&.\/-;#@~%+*-]+))/ig,
'<a href="$1" rel="nofollow noopener noreferrer">$1</a>'
)
),
purifyHtmlConfig
)
);
};
@@ -601,7 +627,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
* @prop {string[]}
* @readonly
*/
const supportedLanguages = ['bg', 'ca', 'cs', 'de', 'es', 'et', 'fr', 'he', 'hu', 'id', 'it', 'jbo', 'lt', 'no', 'nl', 'pl', 'pt', 'oc', 'ru', 'sl', 'uk', 'zh'];
const supportedLanguages = ['bg', 'ca', 'co', 'cs', 'de', 'el', 'es', 'et', 'fi', 'fr', 'he', 'hu', 'id', 'it', 'jbo', 'lt', 'no', 'nl', 'pl', 'pt', 'oc', 'ru', 'sk', 'sl', 'tr', 'uk', 'zh'];
/**
* built in language
@@ -767,7 +793,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
/**
* per language functions to use to determine the plural form
*
* @see {@link https://localization-guide.readthedocs.org/en/latest/l10n/pluralforms.html}
* @see {@link https://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html}
* @name I18n.getPluralForm
* @function
* @param {int} n
@@ -777,9 +803,12 @@ jQuery.PrivateBin = (function($, RawDeflate) {
switch (language)
{
case 'cs':
return n === 1 ? 0 : (n >= 2 && n <=4 ? 1 : 2);
case 'sk':
return n === 1 ? 0 : (n >= 2 && n <= 4 ? 1 : 2);
case 'co':
case 'fr':
case 'oc':
case 'tr':
case 'zh':
return n > 1 ? 1 : 0;
case 'he':
@@ -790,13 +819,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
case 'lt':
return n % 10 === 1 && n % 100 !== 11 ? 0 : ((n % 10 >= 2 && n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
case 'pl':
return n === 1 ? 0 : (n % 10 >= 2 && n %10 <=4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
return n === 1 ? 0 : (n % 10 >= 2 && n %10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
case 'ru':
case 'uk':
return n % 10 === 1 && n % 100 !== 11 ? 0 : (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
case 'sl':
return n % 100 === 1 ? 1 : (n % 100 === 2 ? 2 : (n % 100 === 3 || n % 100 === 4 ? 3 : 0));
// bg, ca, de, en, es, et, hu, it, nl, no, pt
// bg, ca, de, el, en, es, et, fi, hu, it, nl, no, pt
default:
return n !== 1 ? 1 : 0;
}
@@ -2535,7 +2564,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// let showdown convert the HTML and sanitize HTML *afterwards*!
$plainText.html(
DOMPurify.sanitize(
converter.makeHtml(text)
converter.makeHtml(text),
purifyHtmlConfig
)
);
// add table classes from bootstrap css
@@ -2751,6 +2781,34 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$dropzone;
/**
* get blob URL from string data and mime type
*
* @name AttachmentViewer.getBlobUrl
* @private
* @function
* @param {string} data - raw data of attachment
* @param {string} data - mime type of attachment
* @return {string} objectURL
*/
function getBlobUrl(data, mimeType)
{
// Transform into a Blob
const buf = new Uint8Array(data.length);
for (let i = 0; i < data.length; ++i) {
buf[i] = data.charCodeAt(i);
}
const blob = new window.Blob(
[buf],
{
type: mimeType
}
);
// Get blob URL
return window.URL.createObjectURL(blob);
}
/**
* sets the attachment but does not yet show it
*
* @name AttachmentViewer.setAttachment
@@ -2760,44 +2818,42 @@ jQuery.PrivateBin = (function($, RawDeflate) {
*/
me.setAttachment = function(attachmentData, fileName)
{
// data URI format: data:[<mediaType>][;base64],<data>
// skip, if attachments got disabled
if (!$attachmentLink || !$attachmentPreview) return;
// data URI format: data:[<mimeType>][;base64],<data>
// position in data URI string of where data begins
const base64Start = attachmentData.indexOf(',') + 1;
// position in data URI string of where mediaType ends
const mediaTypeEnd = attachmentData.indexOf(';');
// position in data URI string of where mimeType ends
const mimeTypeEnd = attachmentData.indexOf(';');
// extract mediaType
const mediaType = attachmentData.substring(5, mediaTypeEnd);
// extract mimeType
const mimeType = attachmentData.substring(5, mimeTypeEnd);
// extract data and convert to binary
const rawData = attachmentData.substring(base64Start);
const decodedData = rawData.length > 0 ? atob(rawData) : '';
// Transform into a Blob
const buf = new Uint8Array(decodedData.length);
for (let i = 0; i < decodedData.length; ++i) {
buf[i] = decodedData.charCodeAt(i);
}
const blob = new window.Blob([ buf ], { type: mediaType });
// Get Blob URL
const blobUrl = window.URL.createObjectURL(blob);
// IE does not support setting a data URI on an a element
// Using msSaveBlob to download
if (window.Blob && navigator.msSaveBlob) {
$attachmentLink.off('click').on('click', function () {
navigator.msSaveBlob(blob, fileName);
});
} else {
$attachmentLink.attr('href', blobUrl);
}
let blobUrl = getBlobUrl(decodedData, mimeType);
$attachmentLink.attr('href', blobUrl);
if (typeof fileName !== 'undefined') {
$attachmentLink.attr('download', fileName);
}
me.handleBlobAttachmentPreview($attachmentPreview, blobUrl, mediaType);
// sanitize SVG preview
// prevents executing embedded scripts when CSP is not set and user
// right-clicks/long-taps and opens the SVG in a new tab - prevented
// in the preview by use of an img tag, which disables scripts, too
if (mimeType.match(/^image\/.*svg/i)) {
const sanitizedData = DOMPurify.sanitize(
decodedData,
purifySvgConfig
);
blobUrl = getBlobUrl(sanitizedData, mimeType);
}
me.handleBlobAttachmentPreview($attachmentPreview, blobUrl, mimeType);
};
/**
@@ -2808,6 +2864,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
*/
me.showAttachment = function()
{
// skip, if attachments got disabled
if (!$attachment || !$attachmentPreview) return;
$attachment.removeClass('hidden');
if (attachmentHasPreview) {
@@ -3015,13 +3074,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
me.handleBlobAttachmentPreview = function ($targetElement, blobUrl, mimeType) {
if (blobUrl) {
attachmentHasPreview = true;
if (mimeType.match(/image\//i)) {
if (mimeType.match(/^image\//i)) {
$targetElement.html(
$(document.createElement('img'))
.attr('src', blobUrl)
.attr('class', 'img-thumbnail')
);
} else if (mimeType.match(/video\//i)) {
} else if (mimeType.match(/^video\//i)) {
$targetElement.html(
$(document.createElement('video'))
.attr('controls', 'true')
@@ -3032,7 +3091,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
.attr('type', mimeType)
.attr('src', blobUrl))
);
} else if (mimeType.match(/audio\//i)) {
} else if (mimeType.match(/^audio\//i)) {
$targetElement.html(
$(document.createElement('audio'))
.attr('controls', 'true')
@@ -3664,7 +3723,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
for (let i = 0; i < $head.length; ++i) {
newDoc.write($head[i].outerHTML);
}
newDoc.write('</head><body><pre>' + DOMPurify.sanitize(Helper.htmlEntities(paste)) + '</pre></body></html>');
newDoc.write(
'</head><body><pre>' +
DOMPurify.sanitize(
Helper.htmlEntities(paste),
purifyHtmlConfig
) +
'</pre></body></html>'
);
newDoc.close();
}
@@ -5393,11 +5459,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// first load translations
I18n.loadTranslations();
DOMPurify.setConfig({
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
SAFE_FOR_JQUERY: true
});
// Add a hook to make all links open a new window
DOMPurify.addHook('afterSanitizeAttributes', function(node) {
// set all elements owning target to target=_blank

File diff suppressed because it is too large Load Diff

2
js/showdown-2.0.3.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -110,4 +110,3 @@ describe('DiscussionViewer', function () {
);
});
});

View File

@@ -52,12 +52,12 @@ describe('Editor', function () {
!$.PrivateBin.Editor.isPreview() &&
!$('#message').hasClass('hidden')
);
$('#messagepreview').click();
$('#messagepreview').trigger('click');
results.push(
$.PrivateBin.Editor.isPreview() &&
$('#message').hasClass('hidden')
);
$('#messageedit').click();
$('#messageedit').trigger('click');
results.push(
!$.PrivateBin.Editor.isPreview() &&
!$('#message').hasClass('hidden')
@@ -68,4 +68,3 @@ describe('Editor', function () {
);
});
});

View File

@@ -280,7 +280,8 @@ describe('TopNav', function () {
it(
'collapses the navigation when displayed on a small screen',
function () {
var results = [];
var clean = jsdom(),
results = [];
$('body').html(
'<nav><div class="navbar-header"><button type="button" ' +
'class="navbar-toggle collapsed" data-toggle="collapse" ' +
@@ -301,7 +302,11 @@ describe('TopNav', function () {
$('.navbar-toggle').hasClass('collapsed') &&
$('#navbar').attr('aria-expanded') != 'true'
);
$('.navbar-toggle').click();
/*
with the upgrade for bootstrap-3.3.7.js to bootstrap-3.4.1.js
the mobile interface detection changed to check if the
ontouchstart event exists, which broke this section of the test
$('.navbar-toggle').trigger('click');
results.push(
!$('.navbar-toggle').hasClass('collapsed') &&
$('#navbar').attr('aria-expanded') == 'true'
@@ -311,7 +316,8 @@ describe('TopNav', function () {
$('.navbar-toggle').hasClass('collapsed') &&
$('#navbar').attr('aria-expanded') == 'false'
);
cleanup();
*/
clean();
assert.ok(results.every(element => element));
}
);
@@ -670,4 +676,3 @@ describe('TopNav', function () {
);
});
});

Binary file not shown.

View File

@@ -26,9 +26,9 @@
let buff;
if (typeof fetch === 'undefined') {
buff = fs.readFileSync('zlib-1.2.11.wasm');
buff = fs.readFileSync('zlib-1.2.13.wasm');
} else {
const resp = await fetch('js/zlib-1.2.11.wasm');
const resp = await fetch('js/zlib-1.2.13.wasm');
buff = await resp.arrayBuffer();
}
const module = await WebAssembly.compile(buff);

BIN
js/zlib-1.2.13.wasm Normal file

Binary file not shown.

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;
@@ -54,7 +54,7 @@ class Configuration
'urlshortener' => '',
'qrcode' => true,
'icon' => 'identicon',
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\' resource:; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
'zerobincompatibility' => false,
'httpwarning' => true,
'compression' => 'zlib',
@@ -78,9 +78,10 @@ class Configuration
'markdown' => 'Markdown',
),
'traffic' => array(
'limit' => 10,
'header' => null,
'exemptedIp' => null,
'limit' => 10,
'header' => '',
'exempted' => '',
'creators' => '',
),
'purge' => array(
'limit' => 300,
@@ -92,6 +93,10 @@ class Configuration
'model_options' => array(
'dir' => 'data',
),
'yourls' => array(
'signature' => '',
'apiurl' => '',
),
);
/**
@@ -152,8 +157,25 @@ class Configuration
)
) {
$values = array(
'bucket' => getenv('PRIVATEBIN_GCS_BUCKET') ? getenv('PRIVATEBIN_GCS_BUCKET') : null,
'prefix' => 'pastes',
'bucket' => getenv('PRIVATEBIN_GCS_BUCKET') ? getenv('PRIVATEBIN_GCS_BUCKET') : null,
'prefix' => 'pastes',
'uniformacl' => false,
);
} elseif (
$section == 'model_options' && in_array(
$this->_configuration['model']['class'],
array('S3Storage')
)
) {
$values = array(
'region' => null,
'version' => null,
'endpoint' => null,
'accesskey' => null,
'secretkey' => null,
'use_path_style_endpoint' => null,
'bucket' => null,
'prefix' => '',
);
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;
@@ -28,7 +28,7 @@ class Controller
*
* @const string
*/
const VERSION = '1.3.5';
const VERSION = '1.4.0';
/**
* minimal required PHP version
@@ -136,6 +136,9 @@ class Controller
case 'jsonld':
$this->_jsonld($this->_request->getParam('jsonld'));
return;
case 'yourlsproxy':
$this->_yourlsproxy($this->_request->getParam('link'));
break;
}
// output JSON or HTML
@@ -199,13 +202,10 @@ class Controller
ServerSalt::setStore($this->_model->getStore());
TrafficLimiter::setConfiguration($this->_conf);
TrafficLimiter::setStore($this->_model->getStore());
if (!TrafficLimiter::canPass()) {
$this->_return_message(
1, I18n::_(
'Please wait %d seconds between each post.',
$this->_conf->getKey('limit', 'traffic')
)
);
try {
TrafficLimiter::canPass();
} catch (Exception $e) {
$this->_return_message(1, $e->getMessage());
return;
}
@@ -344,8 +344,11 @@ class Controller
header('Content-Security-Policy: ' . $this->_conf->getKey('cspheader'));
header('Cross-Origin-Resource-Policy: same-origin');
header('Cross-Origin-Embedder-Policy: require-corp');
header('Cross-Origin-Opener-Policy: same-origin');
header('Permissions-Policy: interest-cohort=()');
// disabled, because it prevents links from a paste to the same site to
// be opened. Didn't work with `same-origin-allow-popups` either.
// See issue https://github.com/PrivateBin/PrivateBin/issues/970 for details.
// header('Cross-Origin-Opener-Policy: same-origin');
header('Permissions-Policy: browsing-topics=()');
header('Referrer-Policy: no-referrer');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: deny');
@@ -367,10 +370,26 @@ class Controller
setcookie('lang', $languageselection, 0, '', '', true);
}
// strip policies that are unsupported in meta tag
$metacspheader = str_replace(
array(
'frame-ancestors \'none\'; ',
'; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
),
'',
$this->_conf->getKey('cspheader')
);
$page = new View;
$page->assign('NAME', $this->_conf->getKey('name'));
$page->assign('BASEPATH', I18n::_($this->_conf->getKey('basepath')));
$page->assign('CSPHEADER', $metacspheader);
$page->assign('ERROR', I18n::_($this->_error));
$page->assign('NAME', $this->_conf->getKey('name'));
if ($this->_request->getOperation() === 'yourlsproxy') {
$page->assign('SHORTURL', $this->_status);
$page->draw('yourlsproxy');
return;
}
$page->assign('BASEPATH', I18n::_($this->_conf->getKey('basepath')));
$page->assign('STATUS', I18n::_($this->_status));
$page->assign('VERSION', self::VERSION);
$page->assign('DISCUSSION', $this->_conf->getKey('discussion'));
@@ -428,6 +447,22 @@ class Controller
echo $content;
}
/**
* proxies link to YOURLS, updates status or error with response
*
* @access private
* @param string $link
*/
private function _yourlsproxy($link)
{
$yourls = new YourlsProxy($this->_conf, $link);
if ($yourls->isError()) {
$this->_error = $yourls->getError();
} else {
$this->_status = $yourls->getUrl();
}
}
/**
* prepares JSON encoded status message
*

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Data;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Data;
@@ -100,7 +100,7 @@ class Database extends AbstractData
// MySQL uses backticks to quote identifiers by default,
// tell it to expect ANSI SQL double quotes
if (self::$_type === 'mysql' && defined('PDO::MYSQL_ATTR_INIT_COMMAND')) {
$options['opt'][PDO::MYSQL_ATTR_INIT_COMMAND] = "SET sql_mode='ANSI_QUOTES'";
$options['opt'][PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION sql_mode='ANSI_QUOTES'";
}
$tableQuery = self::_getTableQuery(self::$_type);
self::$_db = new PDO(
@@ -277,9 +277,9 @@ class Database extends AbstractData
}
// support v1 attachments
if (array_key_exists('attachment', $paste) && strlen($paste['attachment'])) {
if (array_key_exists('attachment', $paste) && !empty($paste['attachment'])) {
self::$_cache[$pasteid]['attachment'] = $paste['attachment'];
if (array_key_exists('attachmentname', $paste) && strlen($paste['attachmentname'])) {
if (array_key_exists('attachmentname', $paste) && !empty($paste['attachmentname'])) {
self::$_cache[$pasteid]['attachmentname'] = $paste['attachmentname'];
}
}
@@ -552,7 +552,7 @@ class Database extends AbstractData
$position = $key + 1;
if (is_int($parameter)) {
$statement->bindParam($position, $parameter, PDO::PARAM_INT);
} elseif (strlen($parameter) >= 4000) {
} elseif (is_string($parameter) && strlen($parameter) >= 4000) {
$statement->bindParam($position, $parameter, PDO::PARAM_STR, strlen($parameter));
} else {
$statement->bindParam($position, $parameter);
@@ -584,7 +584,7 @@ class Database extends AbstractData
// workaround for https://bugs.php.net/bug.php?id=46728
$result = array();
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
$result[] = array_map('self::_sanitizeClob', $row);
$result[] = array_map('PrivateBin\Data\Database::_sanitizeClob', $row);
}
} else {
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
@@ -593,7 +593,7 @@ class Database extends AbstractData
if (self::$_type === 'oci' && is_array($result)) {
// returned CLOB values are streams, convert these into strings
$result = $firstOnly ?
array_map('self::_sanitizeClob', $result) :
array_map('PrivateBin\Data\Database::_sanitizeClob', $result) :
$result;
}
return $result;
@@ -837,8 +837,10 @@ class Database extends AbstractData
end;'
);
} else {
// CREATE INDEX IF NOT EXISTS not supported as of Oracle MySQL <= 8.0
self::$_db->exec(
'CREATE INDEX IF NOT EXISTS "comment_parent" ON "' .
'CREATE INDEX "' .
self::_sanitizeIdentifier('comment_parent') . '" ON "' .
self::_sanitizeIdentifier('comment') . '" ("pasteid")'
);
}
@@ -941,16 +943,20 @@ class Database extends AbstractData
);
} else {
self::$_db->exec(
'CREATE UNIQUE INDEX IF NOT EXISTS "paste_dataid" ON "' .
'CREATE UNIQUE INDEX IF NOT EXISTS "' .
self::_sanitizeIdentifier('paste_dataid') . '" ON "' .
self::_sanitizeIdentifier('paste') . '" ("dataid")'
);
self::$_db->exec(
'CREATE UNIQUE INDEX IF NOT EXISTS "comment_dataid" ON "' .
'CREATE UNIQUE INDEX IF NOT EXISTS "' .
self::_sanitizeIdentifier('comment_dataid') . '" ON "' .
self::_sanitizeIdentifier('comment') . '" ("dataid")'
);
}
// CREATE INDEX IF NOT EXISTS not supported as of Oracle MySQL <= 8.0
self::$_db->exec(
'CREATE INDEX IF NOT EXISTS "comment_parent" ON "' .
'CREATE INDEX "' .
self::_sanitizeIdentifier('comment_parent') . '" ON "' .
self::_sanitizeIdentifier('comment') . '" ("pasteid")'
);
// no break, continue with updates for 0.22 and later

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Data;
@@ -351,7 +351,7 @@ class Filesystem extends AbstractData
$pastes = array();
$firstLevel = array_filter(
scandir(self::$_path),
'self::_isFirstLevelDir'
'PrivateBin\Data\Filesystem::_isFirstLevelDir'
);
if (count($firstLevel) > 0) {
// try at most 10 times the $batchsize pastes before giving up
@@ -359,7 +359,7 @@ class Filesystem extends AbstractData
$firstKey = array_rand($firstLevel);
$secondLevel = array_filter(
scandir(self::$_path . DIRECTORY_SEPARATOR . $firstLevel[$firstKey]),
'self::_isSecondLevelDir'
'PrivateBin\Data\Filesystem::_isSecondLevelDir'
);
// skip this folder in the next checks if it is empty

View File

@@ -37,6 +37,15 @@ class GoogleCloudStorage extends AbstractData
*/
private static $_prefix = 'pastes';
/**
* bucket acl type
*
* @access private
* @static
* @var bool
*/
private static $_uniformacl = false;
/**
* returns a Google Cloud Storage data backend.
*
@@ -62,6 +71,9 @@ class GoogleCloudStorage extends AbstractData
if (is_array($options) && array_key_exists('prefix', $options)) {
self::$_prefix = $options['prefix'];
}
if (is_array($options) && array_key_exists('uniformacl', $options)) {
self::$_uniformacl = $options['uniformacl'];
}
if (empty(self::$_client)) {
self::$_client = class_exists('StorageClientStub', false) ?
@@ -106,15 +118,18 @@ class GoogleCloudStorage extends AbstractData
$metadata[$k] = strval($v);
}
try {
self::$_bucket->upload(Json::encode($payload), array(
$data = array(
'name' => $key,
'chunkSize' => 262144,
'predefinedAcl' => 'private',
'metadata' => array(
'content-type' => 'application/json',
'metadata' => $metadata,
),
));
);
if (!self::$_uniformacl) {
$data['predefinedAcl'] = 'private';
}
self::$_bucket->upload(Json::encode($payload), $data);
} catch (Exception $e) {
error_log('failed to upload ' . $key . ' to ' . self::$_bucket->name() . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
@@ -277,15 +292,18 @@ class GoogleCloudStorage extends AbstractData
$metadata['value'] = strval($value);
}
try {
self::$_bucket->upload($value, array(
$data = array(
'name' => $key,
'chunkSize' => 262144,
'predefinedAcl' => 'private',
'metadata' => array(
'content-type' => 'application/json',
'metadata' => $metadata,
),
));
);
if (!self::$_uniformacl) {
$data['predefinedAcl'] = 'private';
}
self::$_bucket->upload($value, $data);
} catch (Exception $e) {
error_log('failed to set key ' . $key . ' to ' . self::$_bucket->name() . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));

464
lib/Data/S3Storage.php Normal file
View File

@@ -0,0 +1,464 @@
<?php
/**
* S3.php
*
* an S3 compatible data backend for PrivateBin with CEPH/RadosGW in mind
* see https://docs.ceph.com/en/latest/radosgw/s3/php/
* based on lib/Data/GoogleCloudStorage.php from PrivateBin version 1.4.0
*
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2022 Felix J. Ogris (https://ogris.de/)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.4.1
*
* Installation:
* 1. Make sure you have composer.lock and composer.json in the document root of your PasteBin
* 2. If not, grab a copy from https://github.com/PrivateBin/PrivateBin
* 3. As non-root user, install the AWS SDK for PHP:
* composer require aws/aws-sdk-php
* (On FreeBSD, install devel/php-composer2 prior, e.g.: make -C /usr/ports/devel/php-composer2 install clean)
* 4. In cfg/conf.php, comment out all [model] and [model_options] settings
* 5. Still in cfg/conf.php, add a new [model] section:
* [model]
* class = S3Storage
* 6. Add a new [model_options] as well, e.g. for a Rados gateway as part of your CEPH cluster:
* [model_options]
* region = ""
* version = "2006-03-01"
* endpoint = "https://s3.my-ceph.invalid"
* use_path_style_endpoint = true
* bucket = "my-bucket"
* prefix = "privatebin" (place all PrivateBin data beneath this prefix)
* accesskey = "my-rados-user"
* secretkey = "my-rados-pass"
*/
namespace PrivateBin\Data;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use PrivateBin\Json;
class S3Storage extends AbstractData
{
/**
* S3 client
*
* @access private
* @static
* @var S3Client
*/
private static $_client = null;
/**
* S3 client options
*
* @access private
* @static
* @var array
*/
private static $_options = array();
/**
* S3 bucket
*
* @access private
* @static
* @var string
*/
private static $_bucket = null;
/**
* S3 prefix for all PrivateBin data in this bucket
*
* @access private
* @static
* @var string
*/
private static $_prefix = '';
/**
* returns an S3 data backend.
*
* @access public
* @static
* @param array $options
* @return S3Storage
*/
public static function getInstance(array $options)
{
// if needed initialize the singleton
if (!(self::$_instance instanceof self)) {
self::$_instance = new self;
}
self::$_options = array();
self::$_options['credentials'] = array();
if (is_array($options) && array_key_exists('region', $options)) {
self::$_options['region'] = $options['region'];
}
if (is_array($options) && array_key_exists('version', $options)) {
self::$_options['version'] = $options['version'];
}
if (is_array($options) && array_key_exists('endpoint', $options)) {
self::$_options['endpoint'] = $options['endpoint'];
}
if (is_array($options) && array_key_exists('accesskey', $options)) {
self::$_options['credentials']['key'] = $options['accesskey'];
}
if (is_array($options) && array_key_exists('secretkey', $options)) {
self::$_options['credentials']['secret'] = $options['secretkey'];
}
if (is_array($options) && array_key_exists('use_path_style_endpoint', $options)) {
self::$_options['use_path_style_endpoint'] = filter_var($options['use_path_style_endpoint'], FILTER_VALIDATE_BOOLEAN);
}
if (is_array($options) && array_key_exists('bucket', $options)) {
self::$_bucket = $options['bucket'];
}
if (is_array($options) && array_key_exists('prefix', $options)) {
self::$_prefix = $options['prefix'];
}
if (empty(self::$_client)) {
self::$_client = new S3Client(self::$_options);
}
return self::$_instance;
}
/**
* returns all objects in the given prefix.
*
* @access private
* @param $prefix string with prefix
* @return array all objects in the given prefix
*/
private function _listAllObjects($prefix)
{
$allObjects = array();
$options = array(
'Bucket' => self::$_bucket,
'Prefix' => $prefix,
);
do {
$objectsListResponse = self::$_client->listObjects($options);
$objects = $objectsListResponse['Contents'] ?? array();
foreach ($objects as $object) {
$allObjects[] = $object;
$options['Marker'] = $object['Key'];
}
} while ($objectsListResponse['IsTruncated']);
return $allObjects;
}
/**
* returns the S3 storage object key for $pasteid in self::$_bucket.
*
* @access private
* @param $pasteid string to get the key for
* @return string
*/
private function _getKey($pasteid)
{
if (self::$_prefix != '') {
return self::$_prefix . '/' . $pasteid;
}
return $pasteid;
}
/**
* Uploads the payload in the self::$_bucket under the specified key.
* The entire payload is stored as a JSON document. The metadata is replicated
* as the S3 object's metadata except for the fields attachment, attachmentname
* and salt.
*
* @param $key string to store the payload under
* @param $payload array to store
* @return bool true if successful, otherwise false.
*/
private function _upload($key, $payload)
{
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
foreach ($metadata as $k => $v) {
$metadata[$k] = strval($v);
}
try {
self::$_client->putObject(array(
'Bucket' => self::$_bucket,
'Key' => $key,
'Body' => Json::encode($payload),
'ContentType' => 'application/json',
'Metadata' => $metadata,
));
} catch (S3Exception $e) {
error_log('failed to upload ' . $key . ' to ' . self::$_bucket . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
return false;
}
return true;
}
/**
* @inheritDoc
*/
public function create($pasteid, array $paste)
{
if ($this->exists($pasteid)) {
return false;
}
return $this->_upload($this->_getKey($pasteid), $paste);
}
/**
* @inheritDoc
*/
public function read($pasteid)
{
try {
$object = self::$_client->getObject(array(
'Bucket' => self::$_bucket,
'Key' => $this->_getKey($pasteid),
));
$data = $object['Body']->getContents();
return Json::decode($data);
} catch (S3Exception $e) {
error_log('failed to read ' . $pasteid . ' from ' . self::$_bucket . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
return false;
}
}
/**
* @inheritDoc
*/
public function delete($pasteid)
{
$name = $this->_getKey($pasteid);
try {
$comments = $this->_listAllObjects($name . '/discussion/');
foreach ($comments as $comment) {
try {
self::$_client->deleteObject(array(
'Bucket' => self::$_bucket,
'Key' => $comment['Key'],
));
} catch (S3Exception $e) {
// ignore if already deleted.
}
}
} catch (S3Exception $e) {
// there are no discussions associated with the paste
}
try {
self::$_client->deleteObject(array(
'Bucket' => self::$_bucket,
'Key' => $name,
));
} catch (S3Exception $e) {
// ignore if already deleted
}
}
/**
* @inheritDoc
*/
public function exists($pasteid)
{
return self::$_client->doesObjectExistV2(self::$_bucket, $this->_getKey($pasteid));
}
/**
* @inheritDoc
*/
public function createComment($pasteid, $parentid, $commentid, array $comment)
{
if ($this->existsComment($pasteid, $parentid, $commentid)) {
return false;
}
$key = $this->_getKey($pasteid) . '/discussion/' . $parentid . '/' . $commentid;
return $this->_upload($key, $comment);
}
/**
* @inheritDoc
*/
public function readComments($pasteid)
{
$comments = array();
$prefix = $this->_getKey($pasteid) . '/discussion/';
try {
$entries = $this->_listAllObjects($prefix);
foreach ($entries as $entry) {
$object = self::$_client->getObject(array(
'Bucket' => self::$_bucket,
'Key' => $entry['Key'],
));
$body = JSON::decode($object['Body']->getContents());
$items = explode('/', $entry['Key']);
$body['id'] = $items[3];
$body['parentid'] = $items[2];
$slot = $this->getOpenSlot($comments, (int) $object['Metadata']['created']);
$comments[$slot] = $body;
}
} catch (S3Exception $e) {
// no comments found
}
return $comments;
}
/**
* @inheritDoc
*/
public function existsComment($pasteid, $parentid, $commentid)
{
$name = $this->_getKey($pasteid) . '/discussion/' . $parentid . '/' . $commentid;
return self::$_client->doesObjectExistV2(self::$_bucket, $name);
}
/**
* @inheritDoc
*/
public function purgeValues($namespace, $time)
{
$path = self::$_prefix;
if ($path != '') {
$path .= '/';
}
$path .= 'config/' . $namespace;
try {
foreach ($this->_listAllObjects($path) as $object) {
$name = $object['Key'];
if (strlen($name) > strlen($path) && substr($name, strlen($path), 1) !== '/') {
continue;
}
$head = self::$_client->headObject(array(
'Bucket' => self::$_bucket,
'Key' => $name,
));
if (array_key_exists('Metadata', $head) && array_key_exists('value', $head['Metadata'])) {
$value = $head['Metadata']['value'];
if (is_numeric($value) && intval($value) < $time) {
try {
self::$_client->deleteObject(array(
'Bucket' => self::$_bucket,
'Key' => $name,
));
} catch (S3Exception $e) {
// deleted by another instance.
}
}
}
}
} catch (S3Exception $e) {
// no objects in the bucket yet
}
}
/**
* For S3, the value will also be stored in the metadata for the
* namespaces traffic_limiter and purge_limiter.
* @inheritDoc
*/
public function setValue($value, $namespace, $key = '')
{
$prefix = self::$_prefix;
if ($prefix != '') {
$prefix .= '/';
}
if ($key === '') {
$key = $prefix . 'config/' . $namespace;
} else {
$key = $prefix . 'config/' . $namespace . '/' . $key;
}
$metadata = array('namespace' => $namespace);
if ($namespace != 'salt') {
$metadata['value'] = strval($value);
}
try {
self::$_client->putObject(array(
'Bucket' => self::$_bucket,
'Key' => $key,
'Body' => $value,
'ContentType' => 'application/json',
'Metadata' => $metadata,
));
} catch (S3Exception $e) {
error_log('failed to set key ' . $key . ' to ' . self::$_bucket . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
return false;
}
return true;
}
/**
* @inheritDoc
*/
public function getValue($namespace, $key = '')
{
$prefix = self::$_prefix;
if ($prefix != '') {
$prefix .= '/';
}
if ($key === '') {
$key = $prefix . 'config/' . $namespace;
} else {
$key = $prefix . 'config/' . $namespace . '/' . $key;
}
try {
$object = self::$_client->getObject(array(
'Bucket' => self::$_bucket,
'Key' => $key,
));
return $object['Body']->getContents();
} catch (S3Exception $e) {
return '';
}
}
/**
* @inheritDoc
*/
protected function _getExpiredPastes($batchsize)
{
$expired = array();
$now = time();
$prefix = self::$_prefix;
if ($prefix != '') {
$prefix .= '/';
}
try {
foreach ($this->_listAllObjects($prefix) as $object) {
$head = self::$_client->headObject(array(
'Bucket' => self::$_bucket,
'Key' => $object['Key'],
));
if (array_key_exists('Metadata', $head) && array_key_exists('expire_date', $head['Metadata'])) {
$expire_at = intval($head['Metadata']['expire_date']);
if ($expire_at != 0 && $expire_at < $now) {
array_push($expired, $object['Key']);
}
}
if (count($expired) > $batchsize) {
break;
}
}
} catch (S3Exception $e) {
// no objects in the bucket yet
}
return $expired;
}
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;
@@ -84,7 +84,7 @@ class I18n
*/
public static function _($messageId)
{
return forward_static_call_array('self::translate', func_get_args());
return forward_static_call_array('PrivateBin\I18n::translate', func_get_args());
}
/**
@@ -305,7 +305,7 @@ class I18n
/**
* determines the plural form to use based on current language and given number
*
* From: https://localization-guide.readthedocs.org/en/latest/l10n/pluralforms.html
* From: https://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html
*
* @access protected
* @static
@@ -316,9 +316,12 @@ class I18n
{
switch (self::$_language) {
case 'cs':
return $n == 1 ? 0 : ($n >= 2 && $n <= 4 ? 1 : 2);
case 'sk':
return $n === 1 ? 0 : ($n >= 2 && $n <= 4 ? 1 : 2);
case 'co':
case 'fr':
case 'oc':
case 'tr':
case 'zh':
return $n > 1 ? 1 : 0;
case 'he':
@@ -329,15 +332,15 @@ class I18n
case 'lt':
return $n % 10 === 1 && $n % 100 !== 11 ? 0 : (($n % 10 >= 2 && $n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
case 'pl':
return $n == 1 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
return $n === 1 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
case 'ru':
case 'uk':
return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
return $n % 10 === 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
case 'sl':
return $n % 100 == 1 ? 1 : ($n % 100 == 2 ? 2 : ($n % 100 == 3 || $n % 100 == 4 ? 3 : 0));
// bg, ca, de, en, es, et, hu, it, nl, no, pt
return $n % 100 === 1 ? 1 : ($n % 100 === 2 ? 2 : ($n % 100 === 3 || $n % 100 === 4 ? 3 : 0));
// bg, ca, de, el, en, es, et, fi, hu, it, nl, no, pt
default:
return $n != 1 ? 1 : 0;
return $n !== 1 ? 1 : 0;
}
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Model;

View File

@@ -7,13 +7,14 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Model;
use Exception;
use Identicon\Identicon;
use Jdenticon\Identicon as Jdenticon;
use PrivateBin\Persistence\TrafficLimiter;
use PrivateBin\Vizhash16x16;
@@ -167,6 +168,16 @@ class Comment extends AbstractModel
if ($icon == 'identicon') {
$identicon = new Identicon();
$pngdata = $identicon->getImageDataUri($hmac, 16);
} elseif ($icon == 'jdenticon') {
$jdenticon = new Jdenticon(array(
'hash' => $hmac,
'size' => 16,
'style' => array(
'backgroundColor' => '#fff0', // fully transparent, for dark mode
'padding' => 0,
),
));
$pngdata = $jdenticon->getImageDataUri('png');
} elseif ($icon == 'vizhash') {
$vh = new Vizhash16x16();
$pngdata = 'data:image/png;base64,' . base64_encode(

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Model;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Persistence;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Persistence;

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Persistence;

View File

@@ -8,13 +8,16 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin\Persistence;
use Exception;
use IPLib\Factory;
use IPLib\ParseStringFlag;
use PrivateBin\Configuration;
use PrivateBin\I18n;
/**
* TrafficLimiter
@@ -24,22 +27,22 @@ use PrivateBin\Configuration;
class TrafficLimiter extends AbstractPersistence
{
/**
* time limit in seconds, defaults to 10s
*
* @access private
* @static
* @var int
*/
private static $_limit = 10;
/**
* listed ips are exempted from limits, defaults to null
* listed IPs are the only ones allowed to create, defaults to null
*
* @access private
* @static
* @var string|null
*/
private static $_exemptedIp = null;
private static $_creators = null;
/**
* listed IPs are exempted from limits, defaults to null
*
* @access private
* @static
* @var string|null
*/
private static $_exempted = null;
/**
* key to fetch IP address
@@ -51,28 +54,13 @@ class TrafficLimiter extends AbstractPersistence
private static $_ipKey = 'REMOTE_ADDR';
/**
* set the time limit in seconds
* time limit in seconds, defaults to 10s
*
* @access public
* @access private
* @static
* @param int $limit
* @var int
*/
public static function setLimit($limit)
{
self::$_limit = $limit;
}
/**
* set a list of ip(ranges) as string
*
* @access public
* @static
* @param string $exemptedIps
*/
public static function setExemptedIp($exemptedIp)
{
self::$_exemptedIp = $exemptedIp;
}
private static $_limit = 10;
/**
* set configuration options of the traffic limiter
@@ -83,10 +71,11 @@ class TrafficLimiter extends AbstractPersistence
*/
public static function setConfiguration(Configuration $conf)
{
self::setCreators($conf->getKey('creators', 'traffic'));
self::setExempted($conf->getKey('exempted', 'traffic'));
self::setLimit($conf->getKey('limit', 'traffic'));
self::setExemptedIp($conf->getKey('exemptedIp', 'traffic'));
if (($option = $conf->getKey('header', 'traffic')) !== null) {
if (($option = $conf->getKey('header', 'traffic')) !== '') {
$httpHeader = 'HTTP_' . $option;
if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader])) {
self::$_ipKey = $httpHeader;
@@ -94,6 +83,42 @@ class TrafficLimiter extends AbstractPersistence
}
}
/**
* set a list of creator IP(-ranges) as string
*
* @access public
* @static
* @param string $creators
*/
public static function setCreators($creators)
{
self::$_creators = $creators;
}
/**
* set a list of exempted IP(-ranges) as string
*
* @access public
* @static
* @param string $exempted
*/
public static function setExempted($exempted)
{
self::$_exempted = $exempted;
}
/**
* set the time limit in seconds
*
* @access public
* @static
* @param int $limit
*/
public static function setLimit($limit)
{
self::$_limit = $limit;
}
/**
* get a HMAC of the current visitors IP address
*
@@ -108,7 +133,7 @@ class TrafficLimiter extends AbstractPersistence
}
/**
* Validate $_ipKey against configured ipranges. If matched we will ignore the ip
* validate $_ipKey against configured ipranges. If matched we will ignore the ip
*
* @access private
* @static
@@ -120,8 +145,11 @@ class TrafficLimiter extends AbstractPersistence
if (is_string($ipRange)) {
$ipRange = trim($ipRange);
}
$address = Factory::addressFromString($_SERVER[self::$_ipKey]);
$range = Factory::rangeFromString($ipRange);
$address = Factory::parseAddressString($_SERVER[self::$_ipKey]);
$range = Factory::parseRangeString(
$ipRange,
ParseStringFlag::IPV4_MAYBE_NON_DECIMAL | ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT | ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED
);
// address could not be parsed, we might not be in IP space and try a string comparison instead
if (is_null($address)) {
@@ -136,24 +164,35 @@ class TrafficLimiter extends AbstractPersistence
}
/**
* traffic limiter
*
* Make sure the IP address makes at most 1 request every 10 seconds.
* make sure the IP address is allowed to perfom a request
*
* @access public
* @static
* @return bool
* @throws Exception
* @return true
*/
public static function canPass()
{
// if creators are defined, the traffic limiter will only allow creation
// for these, with no limits, and skip any other rules
if (!empty(self::$_creators)) {
$creatorIps = explode(',', self::$_creators);
foreach ($creatorIps as $ipRange) {
if (self::matchIp($ipRange) === true) {
return true;
}
}
throw new Exception(I18n::_('Your IP is not authorized to create pastes.'));
}
// disable limits if set to less then 1
if (self::$_limit < 1) {
return true;
}
// Check if $_ipKey is exempted from ratelimiting
if (!is_null(self::$_exemptedIp)) {
$exIp_array = explode(',', self::$_exemptedIp);
// check if $_ipKey is exempted from ratelimiting
if (!empty(self::$_exempted)) {
$exIp_array = explode(',', self::$_exempted);
foreach ($exIp_array as $ipRange) {
if (self::matchIp($ipRange) === true) {
return true;
@@ -161,7 +200,7 @@ class TrafficLimiter extends AbstractPersistence
}
}
// this hash is used as an array key, hence a shorter algo is used
// used as array key, which are limited in length, hence using algo with shorter range
$hash = self::getHash('sha256');
$now = time();
$tl = (int) self::$_store->getValue('traffic_limiter', $hash);
@@ -175,6 +214,12 @@ class TrafficLimiter extends AbstractPersistence
if (!self::$_store->setValue((string) $tl, 'traffic_limiter', $hash)) {
error_log('failed to store the traffic limiter, it probably contains outdated information');
}
return $result;
if ($result) {
return true;
}
throw new Exception(I18n::_(
'Please wait %d seconds between each post.',
self::$_limit
));
}
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;
@@ -120,6 +120,7 @@ class Request
if (
!array_key_exists('pasteid', $this->_params) &&
!array_key_exists('jsonld', $this->_params) &&
!array_key_exists('link', $this->_params) &&
array_key_exists('QUERY_STRING', $_SERVER) &&
!empty($_SERVER['QUERY_STRING'])
) {
@@ -135,6 +136,10 @@ class Request
}
} elseif (array_key_exists('jsonld', $this->_params) && !empty($this->_params['jsonld'])) {
$this->_operation = 'jsonld';
} elseif (array_key_exists('link', $this->_params) && !empty($this->_params['link'])) {
if (strpos($this->getRequestUri(), '/shortenviayourls') !== false) {
$this->_operation = 'yourlsproxy';
}
}
}

View File

@@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.3.5
* @version 1.4.0
*/
namespace PrivateBin;

View File

@@ -8,7 +8,7 @@
* @link http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 0.0.5 beta PrivateBin 1.3.5
* @version 0.0.5 beta PrivateBin 1.4.0
*/
namespace PrivateBin;

132
lib/YourlsProxy.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* PrivateBin
*
* a zero-knowledge paste bin
*
* @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.4.0
*/
namespace PrivateBin;
use Exception;
/**
* YourlsProxy
*
* Forwards a URL for shortening to YOURLS (your own URL shortener) and stores
* the result.
*/
class YourlsProxy
{
/**
* error message
*
* @access private
* @var string
*/
private $_error = '';
/**
* shortened URL
*
* @access private
* @var string
*/
private $_url = '';
/**
* constructor
*
* initializes and runs PrivateBin
*
* @access public
* @param string $link
*/
public function __construct(Configuration $conf, $link)
{
if (strpos($link, $conf->getKey('basepath') . '/?') === false) {
$this->_error = 'Trying to shorten a URL that isn\'t pointing at our instance.';
return;
}
$yourls_api_url = $conf->getKey('apiurl', 'yourls');
if (empty($yourls_api_url)) {
$this->_error = 'Error calling YOURLS. Probably a configuration issue, like wrong or missing "apiurl" or "signature".';
return;
}
$data = file_get_contents(
$yourls_api_url, false, stream_context_create(
array(
'http' => array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query(
array(
'signature' => $conf->getKey('signature', 'yourls'),
'format' => 'json',
'action' => 'shorturl',
'url' => $link,
)
),
),
)
)
);
try {
$data = Json::decode($data);
} catch (Exception $e) {
$this->_error = 'Error calling YOURLS. Probably a configuration issue, like wrong or missing "apiurl" or "signature".';
error_log('Error calling YOURLS: ' . $e->getMessage());
return;
}
if (
!is_null($data) &&
array_key_exists('statusCode', $data) &&
$data['statusCode'] == 200 &&
array_key_exists('shorturl', $data)
) {
$this->_url = $data['shorturl'];
} else {
$this->_error = 'Error parsing YOURLS response.';
}
}
/**
* Returns the (untranslated) error message
*
* @access public
* @return string
*/
public function getError()
{
return $this->_error;
}
/**
* Returns the shortened URL
*
* @access public
* @return string
*/
public function getUrl()
{
return $this->_url;
}
/**
* Returns true if any error has occurred
*
* @access public
* @return bool
*/
public function isError()
{
return !empty($this->_error);
}
}

View File

@@ -7,6 +7,7 @@ $isPage = substr($template, -5) === '-page';
<html lang="<?php echo I18n::_('en'); ?>">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="<?php echo I18n::encode($CSPHEADER); ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex" />
@@ -54,10 +55,10 @@ if ($ZEROBINCOMPATIBILITY) :
<?php
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-Yey/0yoaVmSbqMEyyff3DIu8kCPwpHvHf7tY1AuZ1lrX9NPCMg87PwzngMi+VNbe4ilCApmePeuKT869RTcyCQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.13.js" integrity="sha512-Lv4PCbSge8B4odE2blatgggJ/mkX1Ak21e7jL8mY3vzrVHS8FGsrEoqCrizxIJB4sW3T2w5Q+RG7hhUvp7+9tw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/bootstrap-3.3.7.js" integrity="sha512-iztkobsvnjKfAtTNdHkGVjAYTrrtlC7mGp/54c40wowO7LhURYl3gVzzcEqGl/qKXQltJ2HwMrdLcNUdo+N/RQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/bootstrap-3.4.1.js" integrity="sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==" crossorigin="anonymous"></script>
<?php
if ($SYNTAXHIGHLIGHTING) :
?>
@@ -66,13 +67,13 @@ if ($SYNTAXHIGHLIGHTING) :
endif;
if ($MARKDOWN) :
?>
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.0.js" integrity="sha512-UB9jpMTOJLSnVzePuqlSGT34G70wEGqtIWabMeAh+Drnj4/uQ8rFkFn1zkN9vkWp/7nA51U2LmP23H5MJvBXsw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.3.js" integrity="sha512-vcfjvW3UKHD/4vlQx804cqWK88jFmjsWRsZ8/u5YEcyHB1IituxrXDU7TvdqsFVsMnxpE/UIEo25/SYW+puWHw==" crossorigin="anonymous"></script>
<?php
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.3.6.js" integrity="sha512-N1GGPjbqLbwK821ZN7C925WuTwU4aDxz2CEEOXQ6/s6m6MBwVj8fh5fugiE2hzsm0xud3q7jpjZQ4ILnpMREYQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-PTOcxIWIPWCnb5vC4fmQDMqYGerwsu3AndVyPxn9NlQffIWYMPf/p28Z9SIygXsmcYjmTRmUiW5y7df63mNTfg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-sQhu+q8ayRj0LO80orHnhEudlTf5Qx+Yhb/+U84ixMvSdwijuLEHGiEuWctqUPOFSe56L6aeq6z7K0ONpbgaew==" crossorigin="anonymous"></script>
<!-- icon -->
<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />
@@ -84,7 +85,7 @@ endif;
<meta name="theme-color" content="#ffe57e" />
<!-- Twitter/social media cards -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="<?php echo I18n::_('Encrypted note on PrivateBin') ?>" />
<meta name="twitter:title" content="<?php echo I18n::_('Encrypted note on %s', I18n::_($NAME)) ?>" />
<meta name="twitter:description" content="<?php echo I18n::_('Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.') ?>" />
<meta name="twitter:image" content="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" />
<meta property="og:title" content="<?php echo I18n::_($NAME); ?>" />

View File

@@ -4,6 +4,7 @@ use PrivateBin\I18n;
<html lang="<?php echo I18n::_('en'); ?>">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="<?php echo I18n::encode($CSPHEADER); ?>">
<meta name="robots" content="noindex" />
<meta name="google" content="notranslate">
<title><?php echo I18n::_($NAME); ?></title>
@@ -33,7 +34,7 @@ if ($ZEROBINCOMPATIBILITY):
<?php
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-Yey/0yoaVmSbqMEyyff3DIu8kCPwpHvHf7tY1AuZ1lrX9NPCMg87PwzngMi+VNbe4ilCApmePeuKT869RTcyCQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.13.js" integrity="sha512-Lv4PCbSge8B4odE2blatgggJ/mkX1Ak21e7jL8mY3vzrVHS8FGsrEoqCrizxIJB4sW3T2w5Q+RG7hhUvp7+9tw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
<?php
@@ -44,13 +45,13 @@ if ($SYNTAXHIGHLIGHTING):
endif;
if ($MARKDOWN):
?>
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.0.js" integrity="sha512-UB9jpMTOJLSnVzePuqlSGT34G70wEGqtIWabMeAh+Drnj4/uQ8rFkFn1zkN9vkWp/7nA51U2LmP23H5MJvBXsw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.3.js" integrity="sha512-vcfjvW3UKHD/4vlQx804cqWK88jFmjsWRsZ8/u5YEcyHB1IituxrXDU7TvdqsFVsMnxpE/UIEo25/SYW+puWHw==" crossorigin="anonymous"></script>
<?php
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.3.6.js" integrity="sha512-N1GGPjbqLbwK821ZN7C925WuTwU4aDxz2CEEOXQ6/s6m6MBwVj8fh5fugiE2hzsm0xud3q7jpjZQ4ILnpMREYQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-PTOcxIWIPWCnb5vC4fmQDMqYGerwsu3AndVyPxn9NlQffIWYMPf/p28Z9SIygXsmcYjmTRmUiW5y7df63mNTfg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-sQhu+q8ayRj0LO80orHnhEudlTf5Qx+Yhb/+U84ixMvSdwijuLEHGiEuWctqUPOFSe56L6aeq6z7K0ONpbgaew==" crossorigin="anonymous"></script>
<!-- icon -->
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />
@@ -62,7 +63,7 @@ endif;
<meta name="theme-color" content="#ffe57e" />
<!-- Twitter/social media cards -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="<?php echo I18n::_('Encrypted note on PrivateBin') ?>" />
<meta name="twitter:title" content="<?php echo I18n::_('Encrypted note on %s', I18n::_($NAME)) ?>" />
<meta name="twitter:description" content="<?php echo I18n::_('Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.') ?>" />
<meta name="twitter:image" content="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" />
<meta property="og:title" content="<?php echo I18n::_($NAME); ?>" />

27
tpl/yourlsproxy.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
use PrivateBin\I18n;
?><!DOCTYPE html>
<html lang="<?php echo I18n::_('en'); ?>">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="<?php echo I18n::encode($CSPHEADER); ?>">
<meta name="robots" content="noindex" />
<meta name="google" content="notranslate">
<title><?php echo I18n::_($NAME); ?></title>
</head>
<body>
<?php
if (empty($ERROR)) :
?>
<p><?php echo I18n::_('Your paste is <a id="pasteurl" href="%s">%s</a> <span id="copyhint">(Hit [Ctrl]+[c] to copy)</span>', $SHORTURL, $SHORTURL); ?></p>
<?php
else:
?>
<div id="errormessage">
<p><?php echo I18n::_('Could not create paste: %s', $ERROR); ?></p>
</div>
<?php
endif;
?>
</body>
</html>

View File

@@ -48,6 +48,7 @@ class ControllerTest extends PHPUnit_Framework_TestCase
*/
public function testView()
{
$_SERVER['HTTP_HOST'] = 'example.com';
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
$_GET[Helper::getPasteId()] = '';
ob_start();
@@ -64,6 +65,11 @@ class ControllerTest extends PHPUnit_Framework_TestCase
$content,
'doesn\'t output shortener button'
);
$this->assertRegExp(
'# href="https://' . preg_quote($_SERVER['HTTP_HOST']) . '/">switching to HTTPS#',
$content,
'outputs configured https URL correctly'
);
}
/**

View File

@@ -9,6 +9,7 @@ use Identicon\Generator\GdGenerator;
use Identicon\Generator\ImageMagickGenerator;
use Identicon\Generator\SvgGenerator;
use Identicon\Identicon;
use Jdenticon\Identicon as Jdenticon;
use PrivateBin\Vizhash16x16;
@@ -17,7 +18,19 @@ $vizhash = new Vizhash16x16();
$identiconGenerators = array(
'identicon GD' => new Identicon(new GdGenerator()),
'identicon ImageMagick' => new Identicon(new ImageMagickGenerator()),
'identicon SVG' => new Identicon(new SvgGenerator())
'identicon SVG' => new Identicon(new SvgGenerator()),
);
$jdenticon = new Jdenticon(array(
'size' => 16,
'style' => array(
'backgroundColor' => '#fff0', // fully transparent, for dark mode
'padding' => 0,
),
));
$jdenticonGenerators = array(
'jdenticon' => 'png',
'jdenticon ImageMagick' => 'png',
'jdenticon SVG' => 'svg',
);
$results = array(
'vizhash' => array(
@@ -35,21 +48,30 @@ $results = array(
'identicon SVG' => array(
'lengths' => array(),
'time' => 0
)
),
'jdenticon' => array(
'lengths' => array(),
'time' => 0
),
'jdenticon ImageMagick' => array(
'lengths' => array(),
'time' => 0
),
'jdenticon SVG' => array(
'lengths' => array(),
'time' => 0
),
);
$hmacs = array();
echo 'generate ', ITERATIONS, ' hmacs and pre-populate the result array, so tests wont be slowed down', PHP_EOL;
for ($i = 0; $i < ITERATIONS; ++$i) {
$hmacs[$i] = hash_hmac('sha512', '127.0.0.1', bin2hex(random_bytes(256)));
$results['vizhash']['lengths'][$i] = 0;
$results['identicon GD']['lengths'][$i] = 0;
$results['identicon ImageMagick']['lengths'][$i] = 0;
$results['identicon SVG']['lengths'][$i] = 0;
foreach (array_keys($results) as $test) {
$results[$test]['lengths'][$i] = 0;
}
}
echo 'run vizhash tests', PHP_EOL;
$start = microtime(true);
foreach ($hmacs as $i => $hmac) {
@@ -60,7 +82,6 @@ foreach ($hmacs as $i => $hmac) {
}
$results['vizhash']['time'] = microtime(true) - $start;
foreach ($identiconGenerators as $key => $identicon) {
echo 'run ', $key,' tests', PHP_EOL;
$start = microtime(true);
@@ -71,9 +92,35 @@ foreach ($identiconGenerators as $key => $identicon) {
$results[$key]['time'] = microtime(true) - $start;
}
foreach ($jdenticonGenerators as $key => $format) {
echo 'run ', $key,' tests', PHP_EOL;
if ($key === 'jdenticon ImageMagick') {
$jdenticon->enableImageMagick = true;
} else {
$jdenticon->enableImageMagick = false;
}
$start = microtime(true);
foreach ($hmacs as $i => $hmac) {
$jdenticon->setHash($hmac);
$data = $jdenticon->getImageDataUri($format);
$results[$key]['lengths'][$i] = strlen($data);
}
$results[$key]['time'] = microtime(true) - $start;
}
define('PADDING_LENGTH', max(array_map(function ($key) { return strlen($key); }, array_keys($results))) + 1);
define(
'PADDING_LENGTH',
max(
array_map(
function ($key) {
return strlen($key);
},
array_keys($results)
)
) + 1
);
function format_result_line($generator, $min, $max, $avg, $sec) {
echo str_pad($generator, PADDING_LENGTH, ' '), "\t",
str_pad($min, 4, ' ', STR_PAD_LEFT), "\t",
@@ -84,7 +131,10 @@ function format_result_line($generator, $min, $max, $avg, $sec) {
echo PHP_EOL;
format_result_line('Generator:', 'min', 'max', 'avg', 'seconds');
format_result_line(str_repeat('─', PADDING_LENGTH), str_repeat('─', 4), str_repeat('─', 4), str_repeat('─', 4), str_repeat('─', 7));
format_result_line(
str_repeat('─', PADDING_LENGTH), str_repeat('─', 4), str_repeat('─', 4),
str_repeat('─', 4), str_repeat('─', 7)
);
foreach ($results as $generator => $result) {
sort($result['lengths']);
format_result_line(

View File

@@ -15,6 +15,9 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
{
/* Setup Routine */
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
if (!is_dir($this->_path)) {
mkdir($this->_path);
}
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
ServerSalt::setStore($this->_model);
@@ -186,8 +189,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
*/
public function testJsonLdPaste()
{
$paste = Helper::getPaste();
$this->_model->create(Helper::getPasteId(), $paste);
$_GET['jsonld'] = 'paste';
ob_start();
new Controller;
@@ -205,8 +206,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
*/
public function testJsonLdComment()
{
$paste = Helper::getPaste();
$this->_model->create(Helper::getPasteId(), $paste);
$_GET['jsonld'] = 'comment';
ob_start();
new Controller;
@@ -224,8 +223,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
*/
public function testJsonLdPasteMeta()
{
$paste = Helper::getPaste();
$this->_model->create(Helper::getPasteId(), $paste);
$_GET['jsonld'] = 'pastemeta';
ob_start();
new Controller;
@@ -243,8 +240,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
*/
public function testJsonLdCommentMeta()
{
$paste = Helper::getPaste();
$this->_model->create(Helper::getPasteId(), $paste);
$_GET['jsonld'] = 'commentmeta';
ob_start();
new Controller;
@@ -262,8 +257,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
*/
public function testJsonLdInvalid()
{
$paste = Helper::getPaste();
$this->_model->create(Helper::getPasteId(), $paste);
$_GET['jsonld'] = CONF;
ob_start();
new Controller;
@@ -271,4 +264,42 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
ob_end_clean();
$this->assertEquals('{}', $content, 'does not output nasty data');
}
/**
* @runInSeparateProcess
*/
public function testShortenViaYourls()
{
$mock_yourls_service = $this->_path . DIRECTORY_SEPARATOR . 'yourls.json';
$options = parse_ini_file(CONF, true);
$options['main']['basepath'] = 'https://example.com/path';
$options['main']['urlshortener'] = 'https://example.com/path/shortenviayourls?link=';
$options['yourls']['apiurl'] = $mock_yourls_service;
Helper::createIniFile(CONF, $options);
// the real service answer is more complex, but we only look for the shorturl & statusCode
file_put_contents($mock_yourls_service, '{"shorturl":"https:\/\/example.com\/1","statusCode":200}');
$_SERVER['REQUEST_URI'] = '/path/shortenviayourls?link=https%3A%2F%2Fexample.com%2Fpath%2F%3Ffoo%23bar';
$_GET['link'] = 'https://example.com/path/?foo#bar';
ob_start();
new Controller;
$content = ob_get_contents();
ob_end_clean();
$this->assertContains('id="pasteurl" href="https://example.com/1"', $content, 'outputs shortened URL correctly');
}
/**
* @runInSeparateProcess
*/
public function testShortenViaYourlsFailure()
{
$_SERVER['REQUEST_URI'] = '/path/shortenviayourls?link=https%3A%2F%2Fexample.com%2Fpath%2F%3Ffoo%23bar';
$_GET['link'] = 'https://example.com/path/?foo#bar';
ob_start();
new Controller;
$content = ob_get_contents();
ob_end_clean();
$this->assertContains('Error calling YOURLS.', $content, 'outputs error correctly');
}
}

View File

@@ -38,27 +38,74 @@ class TrafficLimiterTest extends PHPUnit_Framework_TestCase
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
sleep(1);
$this->assertFalse(TrafficLimiter::canPass(), 'second request is to fast, may not pass');
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'second request is to fast, may not pass');
}
sleep(4);
$this->assertTrue(TrafficLimiter::canPass(), 'third request waited long enough and may pass');
$_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
$this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass');
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$this->assertFalse(TrafficLimiter::canPass(), 'fifth request is to fast, may not pass');
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'fifth request is to fast, may not pass');
}
}
// exempted IPs configuration
TrafficLimiter::setExemptedIp('1.2.3.4,10.10.10.0/24,2001:1620:2057::/48');
$this->assertFalse(TrafficLimiter::canPass(), 'still too fast and not exempted');
public function testTrafficLimitExempted()
{
TrafficLimiter::setExempted('1.2.3.4,10.10.10/24,2001:1620:2057::/48');
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'not exempted');
}
$_SERVER['REMOTE_ADDR'] = '10.10.10.10';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in exempted range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv4 in exempted range');
$_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in exempted range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv6 in exempted range');
TrafficLimiter::setExemptedIp('127.*,foobar');
$this->assertFalse(TrafficLimiter::canPass(), 'request is to fast, invalid range');
TrafficLimiter::setExempted('127.*,foobar');
$this->assertTrue(TrafficLimiter::canPass(), 'first cached request may pass');
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'request is too fast, invalid range');
}
$_SERVER['REMOTE_ADDR'] = 'foobar';
$this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but non-IP address matches exempted range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but non-IP address matches exempted range');
}
public function testTrafficLimitCreators()
{
TrafficLimiter::setCreators('1.2.3.4,10.10.10/24,2001:1620:2057::/48');
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Your IP is not authorized to create pastes.', 'not a creator');
}
$_SERVER['REMOTE_ADDR'] = '10.10.10.10';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in creator range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but IPv4 in creator range');
$_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
$this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in creator range');
$this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but IPv6 in creator range');
TrafficLimiter::setCreators('127.*,foobar');
try {
$this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
} catch (Exception $e) {
$this->assertEquals($e->getMessage(), 'Your IP is not authorized to create pastes.', 'request is to fast, not a creator');
}
$_SERVER['REMOTE_ADDR'] = 'foobar';
$this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
$this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but non-IP address matches creator');
}
}

View File

@@ -60,6 +60,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
$page->assign('HTTPWARNING', true);
$page->assign('HTTPSLINK', 'https://example.com/');
$page->assign('COMPRESSION', 'zlib');
$page->assign('CSPHEADER', 'default-src \'none\'');
$dir = dir(PATH . 'tpl');
while (false !== ($file = $dir->read())) {
@@ -105,6 +106,10 @@ class ViewTest extends PHPUnit_Framework_TestCase
$content,
$template . ': outputs error correctly'
);
if ($template === 'yourlsproxy') {
// yourlsproxy template only displays error message
continue;
}
$this->assertRegExp(
'#<[^>]+id="password"[^>]*>#',
$content,

75
tst/YourlsProxyTest.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
use PrivateBin\Configuration;
use PrivateBin\YourlsProxy;
class YourlsProxyTest extends PHPUnit_Framework_TestCase
{
private $_conf;
private $_path;
private $_mock_yourls_service;
public function setUp()
{
/* Setup Routine */
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
if (!is_dir($this->_path)) {
mkdir($this->_path);
}
$this->_mock_yourls_service = $this->_path . DIRECTORY_SEPARATOR . 'yourls.json';
$options = parse_ini_file(CONF_SAMPLE, true);
$options['main']['basepath'] = 'https://example.com';
$options['main']['urlshortener'] = 'https://example.com/shortenviayourls?link=';
$options['yourls']['apiurl'] = $this->_mock_yourls_service;
Helper::confBackup();
Helper::createIniFile(CONF, $options);
$this->_conf = new Configuration;
}
public function tearDown()
{
/* Tear Down Routine */
unlink(CONF);
Helper::confRestore();
Helper::rmDir($this->_path);
}
public function testYourlsProxy()
{
// the real service answer is more complex, but we only look for the shorturl & statusCode
file_put_contents($this->_mock_yourls_service, '{"shorturl":"https:\/\/example.com\/1","statusCode":200}');
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
$this->assertFalse($yourls->isError());
$this->assertEquals($yourls->getUrl(), 'https://example.com/1');
}
public function testForeignUrl()
{
$yourls = new YourlsProxy($this->_conf, 'https://other.example.com/?foo#bar');
$this->assertTrue($yourls->isError());
$this->assertEquals($yourls->getError(), 'Trying to shorten a URL that isn\'t pointing at our instance.');
}
public function testYourlsError()
{
// when statusCode is not 200, shorturl may not have been set
file_put_contents($this->_mock_yourls_service, '{"statusCode":403}');
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
$this->assertTrue($yourls->isError());
$this->assertEquals($yourls->getError(), 'Error parsing YOURLS response.');
}
public function testServerError()
{
// simulate some other server error that results in a non-JSON reply
file_put_contents($this->_mock_yourls_service, '500 Internal Server Error');
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
$this->assertTrue($yourls->isError());
$this->assertEquals($yourls->getError(), 'Error calling YOURLS. Probably a configuration issue, like wrong or missing "apiurl" or "signature".');
}
}

View File

@@ -37,57 +37,130 @@ namespace Composer\Autoload;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
@@ -102,9 +175,11 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
@@ -147,11 +222,13 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
@@ -195,8 +272,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
@@ -211,10 +290,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
@@ -234,6 +315,8 @@ class ClassLoader
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
@@ -256,6 +339,8 @@ class ClassLoader
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
@@ -276,6 +361,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
@@ -296,25 +383,44 @@ class ClassLoader
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
@@ -323,6 +429,8 @@ class ClassLoader
return true;
}
return null;
}
/**
@@ -367,6 +475,21 @@ class ClassLoader
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
@@ -438,6 +561,10 @@ class ClassLoader
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
* @private
*/
function includeFile($file)
{

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