Compare commits
No commits in common. "master" and "1.7.6" have entirely different histories.
2
.github/workflows/release.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
|||||||
actions: read
|
actions: read
|
||||||
id-token: write
|
id-token: write
|
||||||
contents: write
|
contents: write
|
||||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
|
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
|
||||||
with:
|
with:
|
||||||
base64-subjects: "${{ needs.release.outputs.hashes }}"
|
base64-subjects: "${{ needs.release.outputs.hashes }}"
|
||||||
draft-release: true
|
draft-release: true
|
||||||
|
2
.github/workflows/test-results.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download and Extract Artifacts
|
- name: Download and Extract Artifacts
|
||||||
uses: dawidd6/action-download-artifact@07ab29fd4a977ae4d2b275087cf67563dfdf0295
|
uses: dawidd6/action-download-artifact@20319c5641d495c8a52e688b7dc5fada6c3a9fbc
|
||||||
with:
|
with:
|
||||||
run_id: ${{ github.event.workflow_run.id }}
|
run_id: ${{ github.event.workflow_run.id }}
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
2
.github/workflows/tests.yml
vendored
@ -121,7 +121,7 @@ jobs:
|
|||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '20'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: 'js/package-lock.json'
|
cache-dependency-path: 'js/package-lock.json'
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ RewriteEngine on
|
|||||||
RewriteCond !%{HTTP_USER_AGENT} "Let's Encrypt validation server" [NC]
|
RewriteCond !%{HTTP_USER_AGENT} "Let's Encrypt validation server" [NC]
|
||||||
RewriteCond %{HTTP_USER_AGENT} ^.*(bot|spider|crawl|https?://|WhatsApp|SkypeUriPreview|facebookexternalhit) [NC]
|
RewriteCond %{HTTP_USER_AGENT} ^.*(bot|spider|crawl|https?://|WhatsApp|SkypeUriPreview|facebookexternalhit) [NC]
|
||||||
RewriteRule .* - [R=403,L]
|
RewriteRule .* - [R=403,L]
|
||||||
AddType application/wasm .wasm
|
|
||||||
|
|
||||||
<IfModule mod_php7.c>
|
<IfModule mod_php7.c>
|
||||||
php_value max_execution_time 30
|
php_value max_execution_time 30
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
# PrivateBin version history
|
# PrivateBin version history
|
||||||
|
|
||||||
## 1.7.7 (not yet released)
|
|
||||||
* ADDED: Switching templates using the web ui (#1501)
|
|
||||||
* CHANGED: Passing large data structures by reference to reduce memory consumption (#858)
|
|
||||||
* CHANGED: Removed use of ctype functions and polyfill library for ctype
|
|
||||||
* CHANGED: Upgrading libraries to: DOMpurify 3.2.5, ip-lib 1.20.0
|
|
||||||
|
|
||||||
## 1.7.6 (2025-02-01)
|
## 1.7.6 (2025-02-01)
|
||||||
* ADDED: Ability to copy the paste by clicking the copy icon button or using the keyboard shortcut ctrl+c/cmd+c (#1390 & #12)
|
* ADDED: Ability to copy the paste by clicking the copy icon button or using the keyboard shortcut ctrl+c/cmd+c (#1390 & #12)
|
||||||
* CHANGED: Allow toggling tab-key-support using `[Ctrl]+[m]` or `[Esc]` in textarea for keyboard navigation (#1386)
|
* CHANGED: Allow toggling tab-key-support using `[Ctrl]+[m]` or `[Esc]` in textarea for keyboard navigation (#1386)
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
||||||
* Felipe Nakandakari - enabled AWS SDK to use default credential provider chain in the S3 Storage backend
|
* Felipe Nakandakari - enabled AWS SDK to use default credential provider chain in the S3 Storage backend
|
||||||
* Aaron Sherber - cache control headers for API calls & use of `shortenviayourls` in query parameters
|
* Aaron Sherber - cache control headers for API calls & use of `shortenviayourls` in query parameters
|
||||||
* Mikhail Romanov - copying to clipboard, UI/UX improvements, templates switching
|
* Mikhail Romanov - copying to clipboard, UI/UX improvements
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
* Hexalyse - French
|
* Hexalyse - French
|
||||||
|
@ -14,8 +14,5 @@ a response within a week (usually during the next weekend). The respondee will
|
|||||||
reply from their personal address and can offer you their GPG public key to
|
reply from their personal address and can offer you their GPG public key to
|
||||||
support end-to-end encrypted communication on sensitive topics or attachments.
|
support end-to-end encrypted communication on sensitive topics or attachments.
|
||||||
|
|
||||||
You can also [use the corresponding GitHub form](https://github.com/PrivateBin/PrivateBin/security/advisories/new)
|
|
||||||
to report a new vulnerability directly on GitHub.
|
|
||||||
|
|
||||||
You can also contact us via the regular issue tracker if the risk of early
|
You can also contact us via the regular issue tracker if the risk of early
|
||||||
publication is low or you would request input from other PrivateBin users.
|
publication is low or you would request input from other PrivateBin users.
|
||||||
|
@ -72,35 +72,6 @@ class Administration
|
|||||||
exit("paste $pasteId successfully deleted" . PHP_EOL);
|
exit("paste $pasteId successfully deleted" . PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* lists all stored paste IDs
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _list_ids()
|
|
||||||
{
|
|
||||||
$ids = $this->_store->getAllPastes();
|
|
||||||
foreach ($ids as $pasteid) {
|
|
||||||
echo $pasteid, PHP_EOL;
|
|
||||||
}
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* deletes all stored pastes (regardless of expiration)
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _delete_all()
|
|
||||||
{
|
|
||||||
$ids = $this->_store->getAllPastes();
|
|
||||||
foreach ($ids as $pasteid) {
|
|
||||||
echo "Deleting paste ID: $pasteid" . PHP_EOL;
|
|
||||||
$this->_store->delete($pasteid);
|
|
||||||
}
|
|
||||||
exit("All pastes successfully deleted" . PHP_EOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes empty directories, if current storage model uses Filesystem
|
* removes empty directories, if current storage model uses Filesystem
|
||||||
*
|
*
|
||||||
@ -153,15 +124,13 @@ class Administration
|
|||||||
{
|
{
|
||||||
echo <<<'EOT'
|
echo <<<'EOT'
|
||||||
Usage:
|
Usage:
|
||||||
administration [--delete <paste id> | --delete-all | --empty-dirs | --help | --list-ids | --purge | --statistics]
|
administration [--delete <paste id> | --empty-dirs | --help | --purge | --statistics]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d, --delete deletes the requested paste ID
|
-d, --delete deletes the requested paste ID
|
||||||
--delete-all deletes all paste IDs
|
|
||||||
-e, --empty-dirs removes empty directories (only if Filesystem storage is
|
-e, --empty-dirs removes empty directories (only if Filesystem storage is
|
||||||
configured)
|
configured)
|
||||||
-h, --help displays this help message
|
-h, --help displays this help message
|
||||||
-l, --list-ids lists all paste IDs
|
|
||||||
-p, --purge purge all expired pastes
|
-p, --purge purge all expired pastes
|
||||||
-s, --statistics reads all stored pastes and comments and reports statistics
|
-s, --statistics reads all stored pastes and comments and reports statistics
|
||||||
EOT, PHP_EOL;
|
EOT, PHP_EOL;
|
||||||
@ -208,8 +177,7 @@ EOT, PHP_EOL;
|
|||||||
self::_help(2);
|
self::_help(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_opts = getopt('hd:epsl', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics', 'list-ids', 'delete-all'));
|
$this->_opts = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics'));
|
||||||
|
|
||||||
if (!$this->_opts) {
|
if (!$this->_opts) {
|
||||||
self::_error_echo('unsupported arguments given');
|
self::_error_echo('unsupported arguments given');
|
||||||
echo PHP_EOL;
|
echo PHP_EOL;
|
||||||
@ -340,12 +308,6 @@ EOT, PHP_EOL;
|
|||||||
$class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model');
|
$class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model');
|
||||||
$this->_store = new $class($this->_conf->getSection('model_options'));
|
$this->_store = new $class($this->_conf->getSection('model_options'));
|
||||||
|
|
||||||
if ($this->_option('l', 'list-ids') !== null) {
|
|
||||||
$this->_list_ids();
|
|
||||||
}
|
|
||||||
if ($this->_option(null, 'delete-all') !== null) {
|
|
||||||
$this->_delete_all();
|
|
||||||
}
|
|
||||||
if (($pasteId = $this->_option('d', 'delete')) !== null) {
|
if (($pasteId = $this->_option('d', 'delete')) !== null) {
|
||||||
$this->_delete($pasteId);
|
$this->_delete($pasteId);
|
||||||
}
|
}
|
||||||
|
@ -42,28 +42,13 @@ defaultformatter = "plaintext"
|
|||||||
; size limit per paste or comment in bytes, defaults to 10 Mebibytes
|
; size limit per paste or comment in bytes, defaults to 10 Mebibytes
|
||||||
sizelimit = 10485760
|
sizelimit = 10485760
|
||||||
|
|
||||||
; by default PrivateBin use "bootstrap" template (tpl/bootstrap.php).
|
; template to include, default is "bootstrap" (tpl/bootstrap.php), also
|
||||||
; Optionally you can enable the template selection menu, which uses
|
|
||||||
; a session cookie to store the choice until the browser is closed.
|
|
||||||
templateselection = false
|
|
||||||
|
|
||||||
; List of available for selection templates when "templateselection" option is enabled
|
|
||||||
availabletemplates[] = "bootstrap"
|
|
||||||
availabletemplates[] = "bootstrap-page"
|
|
||||||
availabletemplates[] = "bootstrap-dark"
|
|
||||||
availabletemplates[] = "bootstrap-dark-page"
|
|
||||||
availabletemplates[] = "bootstrap-compact"
|
|
||||||
availabletemplates[] = "bootstrap-compact-page"
|
|
||||||
availabletemplates[] = "bootstrap5"
|
|
||||||
availabletemplates[] = "page"
|
|
||||||
|
|
||||||
; set the template your installs defaults to, defaults to "bootstrap" (tpl/bootstrap.php), also
|
|
||||||
; available are "page" (tpl/page.php), the classic ZeroBin style and several
|
; available are "page" (tpl/page.php), the classic ZeroBin style and several
|
||||||
; bootstrap variants: "bootstrap-dark", "bootstrap-compact", "bootstrap-page",
|
; bootstrap variants: "bootstrap-dark", "bootstrap-compact", "bootstrap-page",
|
||||||
; which can be combined with "-dark" and "-compact" for "bootstrap-dark-page",
|
; which can be combined with "-dark" and "-compact" for "bootstrap-dark-page"
|
||||||
; "bootstrap-compact-page" and finally "bootstrap5" (tpl/bootstrap5.php) - previews at:
|
; and finally "bootstrap-compact-page" - previews at:
|
||||||
; https://privatebin.info/screenshots.html
|
; https://privatebin.info/screenshots.html
|
||||||
; template = "bootstrap"
|
template = "bootstrap"
|
||||||
|
|
||||||
; (optional) info text to display
|
; (optional) info text to display
|
||||||
; use single, instead of double quotes for HTML attributes
|
; use single, instead of double quotes for HTML attributes
|
||||||
|
@ -26,8 +26,9 @@
|
|||||||
"require" : {
|
"require" : {
|
||||||
"php": "^7.3 || ^8.0",
|
"php": "^7.3 || ^8.0",
|
||||||
"jdenticon/jdenticon": "1.0.2",
|
"jdenticon/jdenticon": "1.0.2",
|
||||||
"mlocati/ip-lib": "1.20.0",
|
"mlocati/ip-lib": "1.18.1",
|
||||||
"symfony/polyfill-php80": "1.31.0",
|
"symfony/polyfill-ctype": "^1.31",
|
||||||
|
"symfony/polyfill-php80": "^1.31",
|
||||||
"yzalis/identicon": "2.0.0"
|
"yzalis/identicon": "2.0.0"
|
||||||
},
|
},
|
||||||
"suggest" : {
|
"suggest" : {
|
||||||
|
105
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "6c7e6dea19e8bfd5641b220cb68c4b65",
|
"content-hash": "0fdf0f08646fa2a4cf9c076131f529f5",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "jdenticon/jdenticon",
|
"name": "jdenticon/jdenticon",
|
||||||
@ -57,16 +57,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mlocati/ip-lib",
|
"name": "mlocati/ip-lib",
|
||||||
"version": "1.20.0",
|
"version": "1.18.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/mlocati/ip-lib.git",
|
"url": "https://github.com/mlocati/ip-lib.git",
|
||||||
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4"
|
"reference": "08bb43b4949069c543ebdf099a6b2c322d0172ab"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/fd45fc3bf08ed6c7e665e2e70562082ac954afd4",
|
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/08bb43b4949069c543ebdf099a6b2c322d0172ab",
|
||||||
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4",
|
"reference": "08bb43b4949069c543ebdf099a6b2c322d0172ab",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -112,7 +112,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/mlocati/ip-lib/issues",
|
"issues": "https://github.com/mlocati/ip-lib/issues",
|
||||||
"source": "https://github.com/mlocati/ip-lib/tree/1.20.0"
|
"source": "https://github.com/mlocati/ip-lib/tree/1.18.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -124,7 +124,86 @@
|
|||||||
"type": "other"
|
"type": "other"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-02-04T17:30:58+00:00"
|
"time": "2024-10-29T15:44:19+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-ctype",
|
||||||
|
"version": "v1.31.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
|
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||||
|
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-ctype": "*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/polyfill",
|
||||||
|
"name": "symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gert de Pagter",
|
||||||
|
"email": "BackEndTea@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for ctype functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"ctype",
|
||||||
|
"polyfill",
|
||||||
|
"portable"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
@ -337,16 +416,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "myclabs/deep-copy",
|
"name": "myclabs/deep-copy",
|
||||||
"version": "1.13.0",
|
"version": "1.12.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414"
|
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
|
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||||
"reference": "024473a478be9df5fdaca2c793f2232fe788e414",
|
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -385,7 +464,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
|
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -393,7 +472,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-02-12T12:17:51+00:00"
|
"time": "2024-11-08T17:47:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
|
@ -22,6 +22,7 @@ for more information.
|
|||||||
### Minimal Requirements
|
### Minimal Requirements
|
||||||
|
|
||||||
- PHP version 7.3 or above
|
- PHP version 7.3 or above
|
||||||
|
- ctype extension
|
||||||
- GD extension (when using identicon or vizhash icons, jdenticon works without it)
|
- GD extension (when using identicon or vizhash icons, jdenticon works without it)
|
||||||
- zlib extension
|
- zlib extension
|
||||||
- some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php)
|
- some disk space or a database supported by [PDO](https://php.net/manual/book.pdo.php)
|
||||||
|
19
i18n/ar.json
@ -218,14 +218,13 @@
|
|||||||
"This secret message can only be displayed once. Would you like to see it now?": "لا يمكن عرض اللصق احرقه بعد قراءته إلا مرة واحدة عند تحميله. هل تريد فتحه الآن؟",
|
"This secret message can only be displayed once. Would you like to see it now?": "لا يمكن عرض اللصق احرقه بعد قراءته إلا مرة واحدة عند تحميله. هل تريد فتحه الآن؟",
|
||||||
"Yes, see it": "نعم، حمله",
|
"Yes, see it": "نعم، حمله",
|
||||||
"Dark Mode": "الوضع الداكن",
|
"Dark Mode": "الوضع الداكن",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "خطأ في ضغط اللصق، بسبب فقدان دعم WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "خطأ في فك ضغط اللصق، متصفحك لا يدعم WebAssembly. الرجاء استخدام متصفح آخر لعرض هذه اللصقة.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "ابدأ من جديد",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "تم نسخ اللصق إلى الحافظة",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "لنسخ اللصق انقر على زر النسخ أو استخدم اختصار الحافظة <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "نسخ الرابط",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "تم نسخ الرابط إلى الحافظة",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "لصق النص",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "مفتاح التبويب يعمل كشخصية (انقر <kbd>Ctrl</kbd>+<kbd>m</kbd> أو <kbd>Esc</kbd> للتبديل)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "السمة"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Cupià u liame",
|
"Copy link": "Cupià u liame",
|
||||||
"Link copied to clipboard": "U liame hè statu cupiatu in u preme’papei",
|
"Link copied to clipboard": "U liame hè statu cupiatu in u preme’papei",
|
||||||
"Paste text": "Testu di l’appiccicu",
|
"Paste text": "Testu di l’appiccicu",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "U tastu di tabulazione ghjova cum’è un caratteru (Appughjate nant’à <kbd>Ctrl</kbd>+<kbd>m</kbd> o <kbd>Scapp</kbd> per scambià)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "U tastu di tabulazione ghjova cum’è un caratteru (Appughjate nant’à <kbd>Ctrl</kbd>+<kbd>m</kbd> o <kbd>Scapp</kbd> per scambià)"
|
||||||
"Theme": "Tema"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Verknüpfung kopieren",
|
"Copy link": "Verknüpfung kopieren",
|
||||||
"Link copied to clipboard": "Verknüpfung wurde in die Zwischenablage kopiert.",
|
"Link copied to clipboard": "Verknüpfung wurde in die Zwischenablage kopiert.",
|
||||||
"Paste text": "Text",
|
"Paste text": "Text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortaste als Zeichen interpretieren (Umschalten durch <kbd>Strg</kbd>+<kbd>m</kbd> oder <kbd>Esc</kbd>)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortaste als Zeichen interpretieren (Umschalten durch <kbd>Strg</kbd>+<kbd>m</kbd> oder <kbd>Esc</kbd>)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
17
i18n/et.json
@ -215,17 +215,16 @@
|
|||||||
"Trying to shorten a URL that isn't pointing at our instance.": "Püüame lühendada URL-i, mis ei viita meie instantsile.",
|
"Trying to shorten a URL that isn't pointing at our instance.": "Püüame lühendada URL-i, mis ei viita meie instantsile.",
|
||||||
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Viga YOURLS-i kutsumisel. Tõenäoliselt konfiguratsiooniprobleem, näiteks vale või puuduv \"apiurl\" või \"signature\".",
|
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Viga YOURLS-i kutsumisel. Tõenäoliselt konfiguratsiooniprobleem, näiteks vale või puuduv \"apiurl\" või \"signature\".",
|
||||||
"Error parsing YOURLS response.": "Viga YOURLS vastuse parsimisel.",
|
"Error parsing YOURLS response.": "Viga YOURLS vastuse parsimisel.",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "Seda turvalist sõnumit saab kuvada vaid ühe korra. \nKas soovid seda näha nüüd?",
|
"This secret message can only be displayed once. Would you like to see it now?": "This secret message can only be displayed once. Would you like to see it now?",
|
||||||
"Yes, see it": "Jah, vaata seda",
|
"Yes, see it": "Yes, see it",
|
||||||
"Dark Mode": "Tume režiim",
|
"Dark Mode": "Tume režiim",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "Alusta uuesti",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Kleebe kopeeriti lõikelauale",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopeeri link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link kopeeriti lõikelauale",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Kleebi tekst",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Teema"
|
|
||||||
}
|
}
|
||||||
|
19
i18n/fi.json
@ -218,14 +218,13 @@
|
|||||||
"This secret message can only be displayed once. Would you like to see it now?": "Tämä salainen viesti voidaan näyttää vain kerran. Haluatko nähdä sen nyt?",
|
"This secret message can only be displayed once. Would you like to see it now?": "Tämä salainen viesti voidaan näyttää vain kerran. Haluatko nähdä sen nyt?",
|
||||||
"Yes, see it": "Kyllä, näet sen",
|
"Yes, see it": "Kyllä, näet sen",
|
||||||
"Dark Mode": "Tumma tila",
|
"Dark Mode": "Tumma tila",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Virhe pakattaessa pastea, koska WebAssembly-tuki puuttuu.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Virhe pasten purkamisessa, selaimesi ei tue WebAssemblyä. Ole hyvä ja käytä toista selainta nähdäksesi tämä paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "Aloita alusta",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Paste kopioitu leikepöydälle",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Voit kopioida pasten painamalla kopioi-painiketta tai käyttämällä leikepöydän oikotietä <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopioi linkki",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Linkki kopioitu leikepöydälle",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Liitä teksti",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulaattori toimii merkkinä (Paina <kbd>Ctrl</kbd>+<kbd>m</kbd> tai <kbd>Esc</kbd> vaihtaaksesi)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Teema"
|
|
||||||
}
|
}
|
||||||
|
11
i18n/fr.json
@ -151,7 +151,7 @@
|
|||||||
"server error or not responding": "Le serveur ne répond pas ou a rencontré une erreur",
|
"server error or not responding": "Le serveur ne répond pas ou a rencontré une erreur",
|
||||||
"Could not post comment: %s": "Impossible de poster le commentaire : %s",
|
"Could not post comment: %s": "Impossible de poster le commentaire : %s",
|
||||||
"Sending paste…": "Envoi du paste…",
|
"Sending paste…": "Envoi du paste…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd> pour copier)</span>",
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span>": "Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur <kbd>Ctrl</kbd>+<kbd>c</kbd> pour copier)</span>",
|
||||||
"Delete data": "Supprimer les données du paste",
|
"Delete data": "Supprimer les données du paste",
|
||||||
"Could not create paste: %s": "Impossible de créer le paste : %s",
|
"Could not create paste: %s": "Impossible de créer le 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?)": "Impossible de déchiffrer le paste : Clé de déchiffrement manquante dans l'URL (Avez-vous utilisé un redirecteur ou un site de réduction d'URL qui supprime une partie de l'URL ?)",
|
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Impossible de déchiffrer le paste : Clé de déchiffrement manquante dans l'URL (Avez-vous utilisé un redirecteur ou un site de réduction d'URL qui supprime une partie de l'URL ?)",
|
||||||
@ -221,11 +221,10 @@
|
|||||||
"Error compressing paste, due to missing WebAssembly support.": "Erreur lors de la compression du paste, en raison du support de WebAssembly manquant.",
|
"Error compressing paste, due to missing WebAssembly support.": "Erreur lors de la compression du paste, en raison du support de WebAssembly manquant.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Erreur lors de la décompression du paste, votre navigateur ne supporte pas WebAssembly. Veuillez utiliser un autre navigateur pour voir ce paste.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Erreur lors de la décompression du paste, votre navigateur ne supporte pas WebAssembly. Veuillez utiliser un autre navigateur pour voir ce paste.",
|
||||||
"Start over": "Recommencer",
|
"Start over": "Recommencer",
|
||||||
"Paste copied to clipboard": "Paste copié dans le presse-papier",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Pour copier-coller appuyer sur le bouton To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Copier le lien",
|
"Copy link": "Copier le lien",
|
||||||
"Link copied to clipboard": "Lien copié dans le presse-papier",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Texte du paste",
|
"Paste text": "Texte du paste",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "La touche de tabulation sert de caractère (Presser <kbd>Ctrl</kbd>+<kbd>m</kbd> ou <kbd>Esc</kbd> pour basculer)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
129
i18n/he.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"PrivateBin": "PrivateBin",
|
"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 הוא שירות pastebin מקוון, מינימליסטי וקוד פתוח, שבו לשרת אין כל ידע על המידע שהודבק. הנתונים מוצפנים ומפוענחים %sבדפדפן%s באמצעות הצפנת AES ב-256 סיביות.",
|
"%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>.": "מידע נוסף בדף <a href=\"https://privatebin.info/\">הפרויקט</a>.",
|
"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": "כיוון שבורות היא ברכה",
|
||||||
"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 דורש PHP %s כדי לפעול.",
|
"%s requires php %s or above to work. Sorry.": "%s דורש PHP %s כדי לפעול.",
|
||||||
@ -29,7 +29,7 @@
|
|||||||
"Create": "צור",
|
"Create": "צור",
|
||||||
"Clone": "שכפול",
|
"Clone": "שכפול",
|
||||||
"Raw text": "טקסט גולמי",
|
"Raw text": "טקסט גולמי",
|
||||||
"Expires": "יפוג ב",
|
"Expires": "Expires",
|
||||||
"Burn after reading": "קוראים-שורפים",
|
"Burn after reading": "קוראים-שורפים",
|
||||||
"Open discussion": "פתיחת דיון",
|
"Open discussion": "פתיחת דיון",
|
||||||
"Password (recommended)": "ססמה (מומלץ)",
|
"Password (recommended)": "ססמה (מומלץ)",
|
||||||
@ -53,11 +53,11 @@
|
|||||||
],
|
],
|
||||||
"%d hours": [
|
"%d hours": [
|
||||||
"שעה אחת",
|
"שעה אחת",
|
||||||
"%d שעות",
|
"%d hours (1st plural)",
|
||||||
"%d שעות",
|
"%d hours (2nd plural)",
|
||||||
"%d שעות",
|
"%d hours (3rd plural)",
|
||||||
"%d שעות",
|
"%d hours (4th plural)",
|
||||||
"%d שעות"
|
"%d hours (5th plural)"
|
||||||
],
|
],
|
||||||
"%d days": [
|
"%d days": [
|
||||||
"יום אחד",
|
"יום אחד",
|
||||||
@ -94,44 +94,44 @@
|
|||||||
"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.": "הערה: זהו שירות בדקה: המידע לא ישמר.",
|
||||||
"This document will expire in %d seconds.": [
|
"This document will expire in %d seconds.": [
|
||||||
"מסמך זה יפוג בעוד שנייה אחת.",
|
"This document will expire in %d second. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות.",
|
"This document will expire in %d seconds. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d שניות."
|
"This document will expire in %d seconds. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d minutes.": [
|
"This document will expire in %d minutes.": [
|
||||||
"מסמך זה יפוג בעוד דקה אחת.",
|
"This document will expire in %d minute. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות.",
|
"This document will expire in %d minutes. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d דקות."
|
"This document will expire in %d minutes. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d hours.": [
|
"This document will expire in %d hours.": [
|
||||||
"מסמך זה יפוג בעוד שעה אחת.",
|
"This document will expire in %d hour. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות.",
|
"This document will expire in %d hours. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d שעות."
|
"This document will expire in %d hours. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d days.": [
|
"This document will expire in %d days.": [
|
||||||
"מסמך זה יפוג בעוד יום אחד.",
|
"This document will expire in %d day. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים.",
|
"This document will expire in %d days. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d ימים."
|
"This document will expire in %d days. (5th plural)"
|
||||||
],
|
],
|
||||||
"This document will expire in %d months.": [
|
"This document will expire in %d months.": [
|
||||||
"מסמך זה יפוג בעוד חודש אחד.",
|
"This document will expire in %d month. (singular)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (1st plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (2nd plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (3rd plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים.",
|
"This document will expire in %d months. (4th plural)",
|
||||||
"מסמך זה יפוג בעוד %d חודשים."
|
"This document will expire in %d months. (5th plural)"
|
||||||
],
|
],
|
||||||
"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?)": "לא ניתן לפענח את הנתונים (מפתח שגוי?)",
|
||||||
@ -170,29 +170,29 @@
|
|||||||
"Markdown": "Markdown",
|
"Markdown": "Markdown",
|
||||||
"Download attachment": "הורדת קובץ מצורף",
|
"Download attachment": "הורדת קובץ מצורף",
|
||||||
"Cloned: '%s'": "שוכפל: '%s'",
|
"Cloned: '%s'": "שוכפל: '%s'",
|
||||||
"The cloned file '%s' was attached to this paste.": "הקובץ '%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": "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.": "File too large, to display a preview. Please download the attachment.",
|
||||||
"Remove 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.": "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 דורש שה-PATH יסתיים ב-\"%s\". אנא עדכן את ה-PATH בקובץ index.php שלך.",
|
"%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>.": "אם הודעה זו לא נעלמת, אנא עיין ב- <a href=\"%s\">שאלות נפוצות אלה למידע לפתרון בעיות</a>.",
|
"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": "לא ניתן לקבל את נתוני ההדבקה: %s",
|
"Could not get paste data: %s": "לא ניתן לקבל את נתוני ההדבקה: %s",
|
||||||
"QR code": "קוד QR",
|
"QR code": "קוד QR",
|
||||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "האתר הזה משתמש בחיבור HTTP בלתי מאובטח! נא להשתמש בזה לבדיקות בלבד.",
|
"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>.",
|
"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 כדי לתמוך ב־API של WebCrypto. כדי לנסות <a href=\"%s\">לעבור ל־HTTPS</a>.",
|
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "יכול להיות שהדפדפן שלך ידרוש חיבור HTTPS כדי לתמוך ב־API של WebCrypto. כדי לנסות <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. אפשר ליצור מסמכים בלתי מוצפנים אך אין אפשרות לקרוא מסמכים מוצפנים.",
|
"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": "בהמתנה למילוי הססמה מצד המשתמש",
|
||||||
@ -209,23 +209,22 @@
|
|||||||
"Close": "סגירה",
|
"Close": "סגירה",
|
||||||
"Encrypted note on %s": "%sהערה מוצפנת ב־",
|
"Encrypted note on %s": "%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 עשוי לחשוף את מפתח הפענוח שלך בכתובת ה-URL.",
|
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||||
"Save paste": "שמור הדבקה",
|
"Save paste": "Save paste",
|
||||||
"Your IP is not authorized to create pastes.": "ה-IP שלך אינו מורשה ליצור הדבקות.",
|
"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.": "מנסים לקצר כתובת URL שאינה מצביעה על המערכת שלנו.",
|
"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\".": "שגיאה בעת קריאה ל-YOURLS. כנראה מדובר בבעיה בהגדרות, כמו \"apiurl\" או \"signature\" שגויים או חסרים.",
|
"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.": "שגיאה בניתוח התגובה מ-YOURLS.",
|
"Error parsing YOURLS response.": "Error parsing YOURLS response.",
|
||||||
"This secret message can only be displayed once. Would you like to see it now?": "ההודעה הסודית הזו יכולה להוצג רק פעם אחת. האם תרצה לראות אותה עכשיו?",
|
"This secret message can only be displayed once. Would you like to see it now?": "This secret message can only be displayed once. Would you like to see it now?",
|
||||||
"Yes, see it": "כן, ראה אותה",
|
"Yes, see it": "Yes, see it",
|
||||||
"Dark Mode": "מצב כהה",
|
"Dark Mode": "Dark Mode",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "שגיאה בדחיסת ההדבקה, עקב חוסר תמיכה ב-WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Error compressing paste, due to missing WebAssembly support.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "שגיאה בהפקת ההדבקה, הדפדפן שלך לא תומך ב-WebAssembly. אנא השתמש בדפדפן אחר כדי לצפות בהדבקה זו.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.",
|
||||||
"Start over": "להתחיל מחדש",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "ההדבקה הועתקה ללוח",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "על מנת להעתיק את ההדבקה, לחץ על כפתור ההעתקה או השתמש בקיצור הדרך ללוח <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "העתק קישור",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "הקישור הועתק ללוח",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "הדבק טקסט",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "משטח ה-tab פועל כמקש תו (לחץ על <kbd>Ctrl</kbd>+<kbd>m</kbd> או <kbd>Esc</kbd> להחלפה)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "נושא"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copia il link",
|
"Copy link": "Copia il link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Testo del messaggio",
|
"Paste text": "Testo del messaggio",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
17
i18n/nl.json
@ -143,7 +143,7 @@
|
|||||||
"Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
|
"Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
|
||||||
"Add comment": "Commentaar toevoegen",
|
"Add comment": "Commentaar toevoegen",
|
||||||
"Optional nickname…": "Optionele bijnaam…",
|
"Optional nickname…": "Optionele bijnaam…",
|
||||||
"Post comment": "Plaats commentaar",
|
"Post comment": "Plaats een commentaar",
|
||||||
"Sending comment…": "Commentaar verzenden…",
|
"Sending comment…": "Commentaar verzenden…",
|
||||||
"Comment posted.": "Commentaar geplaatst.",
|
"Comment posted.": "Commentaar geplaatst.",
|
||||||
"Could not refresh display: %s": "Kon de weergave niet vernieuwen: %s",
|
"Could not refresh display: %s": "Kon de weergave niet vernieuwen: %s",
|
||||||
@ -220,12 +220,11 @@
|
|||||||
"Dark Mode": "Donkere modus",
|
"Dark Mode": "Donkere modus",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Fout bij het comprimeren van notitie door ontbrekende ondersteuning voor WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Fout bij het comprimeren van notitie door ontbrekende ondersteuning voor WebAssembly.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Fout bij het decomprimeren van de notitie, uw browser ondersteunt WebAssembly niet. Gebruik een andere browser om deze notitie te bekijken.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Fout bij het decomprimeren van de notitie, uw browser ondersteunt WebAssembly niet. Gebruik een andere browser om deze notitie te bekijken.",
|
||||||
"Start over": "Opnieuw beginnen",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Notitie gekopieerd naar klembord",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Om te kopiëren en plakken druk je op de knop Kopiëren of gebruik je de sneltoets op het klembord <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopieer link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link gekopieerd naar klembord",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Tekst plakken",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulatortoets dient als teken (gebruik <kbd>Ctrl</kbd>+<kbd>m</kbd> of <kbd>Esc</kbd> om te schakelen)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
15
i18n/pl.json
@ -220,12 +220,11 @@
|
|||||||
"Dark Mode": "Ciemny motyw",
|
"Dark Mode": "Ciemny motyw",
|
||||||
"Error compressing paste, due to missing WebAssembly support.": "Błąd kompresowania wklejenia przez brak obsługi WebAssembly.",
|
"Error compressing paste, due to missing WebAssembly support.": "Błąd kompresowania wklejenia przez brak obsługi WebAssembly.",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Błąd dekompresowania wklejenia przez brak obsługi WebAssembly przez przeglądarkę. Użyj innej przeglądarki, aby zobaczyć to wklejenie.",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "Błąd dekompresowania wklejenia przez brak obsługi WebAssembly przez przeglądarkę. Użyj innej przeglądarki, aby zobaczyć to wklejenie.",
|
||||||
"Start over": "Zacznij od nowa",
|
"Start over": "Start over",
|
||||||
"Paste copied to clipboard": "Wklejka skopiowana do schowka",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Aby skopiować wklejkę, naciśnij przycisk kopiowania lub użyj skrótu schowka <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "Kopiuj link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link został skopiowany do schowka",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Wklej tekst",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Klawisz Tabulatora służy jako znak (przytrzymaj <kbd>Ctrl</kbd>+<kbd>m</kbd> lub <kbd>Esc</kbd> aby przełączać)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Motyw"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Скопировать ссылку",
|
"Copy link": "Скопировать ссылку",
|
||||||
"Link copied to clipboard": "Ссылка скопирована в буфер обмена",
|
"Link copied to clipboard": "Ссылка скопирована в буфер обмена",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Тема"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,5 @@
|
|||||||
"Copy link": "Copy link",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "Link copied to clipboard",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "Paste text",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "Theme"
|
|
||||||
}
|
}
|
||||||
|
13
i18n/zh.json
@ -221,11 +221,10 @@
|
|||||||
"Error compressing paste, due to missing WebAssembly support.": "由于缺少 WebAssembly 支持,在压缩粘贴时出错。",
|
"Error compressing paste, due to missing WebAssembly support.": "由于缺少 WebAssembly 支持,在压缩粘贴时出错。",
|
||||||
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "解压粘贴时出错,您的浏览器不支持 WebAssembly。请使用其他浏览器查看此粘贴。",
|
"Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.": "解压粘贴时出错,您的浏览器不支持 WebAssembly。请使用其他浏览器查看此粘贴。",
|
||||||
"Start over": "重新开始",
|
"Start over": "重新开始",
|
||||||
"Paste copied to clipboard": "粘贴内容已复制到剪贴板",
|
"Paste copied to clipboard": "Paste copied to clipboard",
|
||||||
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "要复制粘贴内容,请点击复制按钮或使用快捷键 <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>。",
|
"To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "To copy paste press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||||
"Copy link": "复制链接",
|
"Copy link": "Copy link",
|
||||||
"Link copied to clipboard": "链接已复制到剪贴板",
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Paste text": "粘贴文本",
|
"Paste text": "Paste text",
|
||||||
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tab 键可作为字符(按 <kbd>Ctrl</kbd>+<kbd>m</kbd> 或 <kbd>Esc</kbd> 切换开关)",
|
"Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)": "Tabulator key serves as character (Hit <kbd>Ctrl</kbd>+<kbd>m</kbd> or <kbd>Esc</kbd> to toggle)"
|
||||||
"Theme": "主题"
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 749 B |
Before Width: | Height: | Size: 180 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 253 B |
BIN
img/icon_new.png
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 157 B |
BIN
img/icon_qr.png
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 299 B |
BIN
img/icon_raw.png
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
15
js/common.js
@ -5,6 +5,7 @@ global.assert = require('assert');
|
|||||||
global.jsc = require('jsverify');
|
global.jsc = require('jsverify');
|
||||||
global.jsdom = require('jsdom-global');
|
global.jsdom = require('jsdom-global');
|
||||||
global.cleanup = global.jsdom();
|
global.cleanup = global.jsdom();
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
global.fs = require('fs');
|
global.fs = require('fs');
|
||||||
global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ require('./prettify');
|
|||||||
global.prettyPrint = window.PR.prettyPrint;
|
global.prettyPrint = window.PR.prettyPrint;
|
||||||
global.prettyPrintOne = window.PR.prettyPrintOne;
|
global.prettyPrintOne = window.PR.prettyPrintOne;
|
||||||
global.showdown = require('./showdown-2.1.0');
|
global.showdown = require('./showdown-2.1.0');
|
||||||
global.DOMPurify = require('./purify-3.2.5');
|
global.DOMPurify = require('./purify-3.2.4');
|
||||||
global.baseX = require('./base-x-4.0.0').baseX;
|
global.baseX = require('./base-x-4.0.0').baseX;
|
||||||
global.Legacy = require('./legacy').Legacy;
|
global.Legacy = require('./legacy').Legacy;
|
||||||
require('./bootstrap-3.4.1');
|
require('./bootstrap-3.4.1');
|
||||||
@ -78,16 +79,8 @@ function parseMime(line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// common testing helper functions
|
// common testing helper functions
|
||||||
// as of jsDOM 22 the base64 functions provided in the DOM are more restrictive
|
exports.atob = atob;
|
||||||
// than browser implementation and throw when being passed invalid unicode
|
exports.btoa = btoa;
|
||||||
// codepoints - as we use these in the encryption with binary data, we need
|
|
||||||
// these to be character encoding agnostic
|
|
||||||
exports.atob = function(encoded) {
|
|
||||||
return Buffer.from(encoded, 'base64').toString('binary');
|
|
||||||
}
|
|
||||||
exports.btoa = function(text) {
|
|
||||||
return Buffer.from(text, 'binary').toString('base64');
|
|
||||||
}
|
|
||||||
|
|
||||||
// provides random lowercase characters from a to z
|
// provides random lowercase characters from a to z
|
||||||
exports.jscA2zString = function() {
|
exports.jscA2zString = function() {
|
||||||
|
1988
js/package-lock.json
generated
@ -6,11 +6,13 @@
|
|||||||
"directories": {
|
"directories": {
|
||||||
"test": "test"
|
"test": "test"
|
||||||
},
|
},
|
||||||
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@peculiar/webcrypto": "^1.5.0",
|
"jsdom": "^9.12.0",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom-global": "^2.1.1",
|
||||||
"jsdom-global": "^3.0.2",
|
"jsdom-url": "^2.2.1",
|
||||||
"jsverify": "^0.8.3"
|
"jsverify": "^0.8.3",
|
||||||
|
"@peculiar/webcrypto": "^1.1.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
|
@ -58,6 +58,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
|||||||
*/
|
*/
|
||||||
const purifyHtmlConfig = {
|
const purifyHtmlConfig = {
|
||||||
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
|
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|magnet):)/i,
|
||||||
|
SAFE_FOR_JQUERY: true,
|
||||||
USE_PROFILES: {
|
USE_PROFILES: {
|
||||||
html: true
|
html: true
|
||||||
}
|
}
|
||||||
@ -3932,26 +3933,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
|||||||
*/
|
*/
|
||||||
function setLanguage(event)
|
function setLanguage(event)
|
||||||
{
|
{
|
||||||
let lang = $(event.target).data('lang') || event.target.value;
|
document.cookie = 'lang=' + $(event.target).data('lang') + '; SameSite=Lax; Secure';
|
||||||
|
|
||||||
document.cookie = 'lang=' + lang + '; SameSite=Lax; Secure';
|
|
||||||
window.location.reload();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* save the template in a cookie and reloads the page
|
|
||||||
*
|
|
||||||
* @name TopNav.setTemplate
|
|
||||||
* @private
|
|
||||||
* @function
|
|
||||||
* @param {Event} event
|
|
||||||
*/
|
|
||||||
function setTemplate(event)
|
|
||||||
{
|
|
||||||
let template = $(event.target).data('template') || event.target.value;
|
|
||||||
|
|
||||||
document.cookie = 'template=' + template + '; SameSite=Lax; Secure';
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
@ -4643,12 +4625,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
|||||||
// bootstrap template drop down
|
// bootstrap template drop down
|
||||||
$('#language ul.dropdown-menu li a').click(setLanguage);
|
$('#language ul.dropdown-menu li a').click(setLanguage);
|
||||||
// page template drop down
|
// page template drop down
|
||||||
$('#language select').change(setLanguage);
|
$('#language select option').click(setLanguage);
|
||||||
|
|
||||||
// bootstrap template drop down
|
|
||||||
$('#template ul.dropdown-menu li a').click(setTemplate);
|
|
||||||
// page template drop down
|
|
||||||
$('#template select').change(setTemplate);
|
|
||||||
|
|
||||||
// bind events
|
// bind events
|
||||||
$burnAfterReading.change(changeBurnAfterReading);
|
$burnAfterReading.change(changeBurnAfterReading);
|
||||||
|
2
js/purify-3.2.4.js
Normal file
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
var common = require('../common');
|
||||||
|
|
||||||
describe('AttachmentViewer', function () {
|
describe('AttachmentViewer', function () {
|
||||||
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
|
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
|
||||||
@ -14,12 +14,11 @@ describe('AttachmentViewer', function () {
|
|||||||
'string',
|
'string',
|
||||||
function (mimeType, rawdata, filename, prefix, postfix) {
|
function (mimeType, rawdata, filename, prefix, postfix) {
|
||||||
let clean = jsdom(),
|
let clean = jsdom(),
|
||||||
data = 'data:' + mimeType + ';base64,' + common.btoa(rawdata),
|
data = 'data:' + mimeType + ';base64,' + btoa(rawdata),
|
||||||
mimePrefix = mimeType.substring(0, 6),
|
|
||||||
previewSupported = (
|
previewSupported = (
|
||||||
mimePrefix === 'image/' ||
|
mimeType.substring(0, 6) === 'image/' ||
|
||||||
mimePrefix === 'audio/' ||
|
mimeType.substring(0, 6) === 'audio/' ||
|
||||||
mimePrefix === 'video/' ||
|
mimeType.substring(0, 6) === 'video/' ||
|
||||||
mimeType.match(/\/pdf/i)
|
mimeType.match(/\/pdf/i)
|
||||||
),
|
),
|
||||||
results = [],
|
results = [],
|
||||||
@ -49,7 +48,6 @@ describe('AttachmentViewer', function () {
|
|||||||
$('#attachment').hasClass('hidden') &&
|
$('#attachment').hasClass('hidden') &&
|
||||||
$('#attachmentPreview').hasClass('hidden')
|
$('#attachmentPreview').hasClass('hidden')
|
||||||
);
|
);
|
||||||
global.atob = common.atob;
|
|
||||||
if (filename.length) {
|
if (filename.length) {
|
||||||
$.PrivateBin.AttachmentViewer.setAttachment(data, filename);
|
$.PrivateBin.AttachmentViewer.setAttachment(data, filename);
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,9 +19,10 @@ describe('Check', function () {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
Legacy.Check.init();
|
Legacy.Check.init();
|
||||||
const result = Legacy.Check.getInit() && !Legacy.Check.getStatus();
|
const result1 = Legacy.Check.getInit() && !Legacy.Check.getStatus(),
|
||||||
|
result2 = (document.getElementById('errormessage').className !== 'hidden');
|
||||||
clean();
|
clean();
|
||||||
return result;
|
return result1 && result2;
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 10});
|
{tests: 10});
|
||||||
@ -66,10 +67,7 @@ describe('Check', function () {
|
|||||||
'url': (secureProtocol ? 'https' : 'http' ) + '://' + domain.join('') + '/'
|
'url': (secureProtocol ? 'https' : 'http' ) + '://' + domain.join('') + '/'
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
Legacy.Check.init();
|
Legacy.Check.init();
|
||||||
const result1 = Legacy.Check.getInit() && Legacy.Check.getStatus(),
|
const result1 = Legacy.Check.getInit() && Legacy.Check.getStatus(),
|
||||||
result2 = secureProtocol === (document.getElementById('httpnotice').className === 'hidden');
|
result2 = secureProtocol === (document.getElementById('httpnotice').className === 'hidden');
|
||||||
|
@ -4,136 +4,120 @@ const common = require('../common');
|
|||||||
describe('CopyToClipboard', function() {
|
describe('CopyToClipboard', function() {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
|
|
||||||
describe ('Copy paste to clipboard', function () {
|
describe ('Copy paste co clipboard', function () {
|
||||||
jsc.property('Copy with button click',
|
jsc.property('Copy with button click', common.jscFormats(), 'nestring', async function (format, text) {
|
||||||
common.jscFormats(),
|
var clean = jsdom();
|
||||||
'nestring',
|
common.enableClipboard();
|
||||||
async function (format, text) {
|
|
||||||
var clean = jsdom();
|
$('body').html(
|
||||||
common.enableClipboard();
|
'<div id="placeholder" class="hidden">+++ no paste text ' +
|
||||||
|
'+++</div><div id="prettymessage" class="hidden">' +
|
||||||
|
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
||||||
|
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
||||||
|
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
||||||
|
'</div><div id="plaintext" class="hidden"></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
$.PrivateBin.PasteViewer.init();
|
||||||
|
$.PrivateBin.PasteViewer.setFormat(format);
|
||||||
|
$.PrivateBin.PasteViewer.setText(text);
|
||||||
|
$.PrivateBin.PasteViewer.run();
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
|
||||||
|
$('#prettyMessageCopyBtn').trigger('click');
|
||||||
|
|
||||||
$('body').html(
|
const savedToClipboardText = await navigator.clipboard.readText();
|
||||||
'<div id="placeholder" class="hidden">+++ no paste text ' +
|
|
||||||
'+++</div><div id="prettymessage" class="hidden">' +
|
clean();
|
||||||
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
|
||||||
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
return text === savedToClipboardText;
|
||||||
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
});
|
||||||
'</div><div id="plaintext" class="hidden"></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$.PrivateBin.PasteViewer.init();
|
|
||||||
$.PrivateBin.PasteViewer.setFormat(format);
|
|
||||||
$.PrivateBin.PasteViewer.setText(text);
|
|
||||||
$.PrivateBin.PasteViewer.run();
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
|
|
||||||
$('#prettyMessageCopyBtn').trigger('click');
|
|
||||||
|
|
||||||
const savedToClipboardText = await navigator.clipboard.readText();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return text === savedToClipboardText;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unfortunately in JSVerify impossible to check if copy with shortcut when user selected some text on the page
|
* Unfortunately in JSVerify impossible to check if copy with shortcut when user selected some text on the page
|
||||||
* (the copy paste to clipboard should not work in this case) due to lacking window.getSelection() in jsdom.
|
* (the copy paste to clipboard should not work in this case) due to lucking window.getSelection() in jsdom.
|
||||||
*/
|
*/
|
||||||
jsc.property('Copy with keyboard shortcut',
|
jsc.property('Copy with keyboard shortcut', common.jscFormats(), 'nestring', async function (format, text) {
|
||||||
common.jscFormats(),
|
|
||||||
'nestring',
|
|
||||||
async function (format, text) {
|
|
||||||
var clean = jsdom();
|
|
||||||
common.enableClipboard();
|
|
||||||
|
|
||||||
$('body').html(
|
|
||||||
'<div id="placeholder">+++ no paste text ' +
|
|
||||||
'+++</div><div id="prettymessage" class="hidden">' +
|
|
||||||
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
|
||||||
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
|
||||||
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
|
||||||
'</div><div id="plaintext" class="hidden"></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$.PrivateBin.PasteViewer.init();
|
|
||||||
$.PrivateBin.PasteViewer.setFormat(format);
|
|
||||||
$.PrivateBin.PasteViewer.setText(text);
|
|
||||||
$.PrivateBin.PasteViewer.run();
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
|
|
||||||
$('body').trigger('copy');
|
|
||||||
|
|
||||||
const copiedTextWithoutSelectedText = await navigator.clipboard.readText();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return copiedTextWithoutSelectedText === text;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
jsc.property('Copy link to clipboard',
|
|
||||||
'nestring',
|
|
||||||
async function (text) {
|
|
||||||
var clean = jsdom();
|
var clean = jsdom();
|
||||||
common.enableClipboard();
|
common.enableClipboard();
|
||||||
|
|
||||||
$('body').html('<button id="copyLink"></button>');
|
$('body').html(
|
||||||
|
'<div id="placeholder">+++ no paste text ' +
|
||||||
|
'+++</div><div id="prettymessage" class="hidden">' +
|
||||||
|
'<button type="button" id="prettyMessageCopyBtn"><svg id="copyIcon"></svg>' +
|
||||||
|
'<svg id="copySuccessIcon"></svg></button><pre ' +
|
||||||
|
'id="prettyprint" class="prettyprint linenums:1"></pre>' +
|
||||||
|
'</div><div id="plaintext" class="hidden"></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
$.PrivateBin.PasteViewer.init();
|
||||||
|
$.PrivateBin.PasteViewer.setFormat(format);
|
||||||
|
$.PrivateBin.PasteViewer.setText(text);
|
||||||
|
$.PrivateBin.PasteViewer.run();
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
$.PrivateBin.CopyToClipboard.setUrl(text);
|
|
||||||
|
|
||||||
$('#copyLink').trigger('click');
|
$('body').trigger('copy');
|
||||||
|
|
||||||
const copiedText = await navigator.clipboard.readText();
|
const copiedTextWithoutSelectedText = await navigator.clipboard.readText();
|
||||||
|
|
||||||
clean();
|
clean();
|
||||||
|
|
||||||
return text === copiedText;
|
return copiedTextWithoutSelectedText === text;
|
||||||
}
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
|
|
||||||
|
jsc.property('Copy link to clipboard', 'nestring', async function (text) {
|
||||||
|
var clean = jsdom();
|
||||||
|
common.enableClipboard();
|
||||||
|
|
||||||
|
$('body').html('<button id="copyLink"></button>');
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.setUrl(text);
|
||||||
|
|
||||||
|
$('#copyLink').trigger('click');
|
||||||
|
|
||||||
|
const copiedText = await navigator.clipboard.readText();
|
||||||
|
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return text === copiedText;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Keyboard shortcut hint', function () {
|
describe('Keyboard shortcut hint', function () {
|
||||||
jsc.property('Show hint',
|
jsc.property('Show hint', 'nestring', function (text) {
|
||||||
'nestring',
|
var clean = jsdom();
|
||||||
function (text) {
|
|
||||||
var clean = jsdom();
|
$('body').html('<small id="copyShortcutHintText"></small>');
|
||||||
|
|
||||||
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.showKeyboardShortcutHint();
|
||||||
|
|
||||||
|
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
||||||
|
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return keyboardShortcutHint.length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
$('body').html('<small id="copyShortcutHintText"></small>');
|
jsc.property('Hide hint', 'nestring', function (text) {
|
||||||
|
var clean = jsdom();
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
$.PrivateBin.CopyToClipboard.showKeyboardShortcutHint();
|
$('body').html('<small id="copyShortcutHintText">' + text + '</small>');
|
||||||
|
|
||||||
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
$.PrivateBin.CopyToClipboard.init();
|
||||||
|
$.PrivateBin.CopyToClipboard.hideKeyboardShortcutHint();
|
||||||
clean();
|
|
||||||
|
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
||||||
return keyboardShortcutHint.length > 0;
|
|
||||||
}
|
clean();
|
||||||
);
|
|
||||||
|
return keyboardShortcutHint.length === 0;
|
||||||
jsc.property('Hide hint',
|
});
|
||||||
'nestring',
|
|
||||||
function (text) {
|
|
||||||
var clean = jsdom();
|
|
||||||
|
|
||||||
$('body').html('<small id="copyShortcutHintText">' + text + '</small>');
|
|
||||||
|
|
||||||
$.PrivateBin.CopyToClipboard.init();
|
|
||||||
$.PrivateBin.CopyToClipboard.hideKeyboardShortcutHint();
|
|
||||||
|
|
||||||
const keyboardShortcutHint = $('#copyShortcutHintText').text();
|
|
||||||
|
|
||||||
clean();
|
|
||||||
|
|
||||||
return keyboardShortcutHint.length === 0;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
require('../common');
|
||||||
|
|
||||||
describe('CryptTool', function () {
|
describe('CryptTool', function () {
|
||||||
describe('cipher & decipher', function () {
|
describe('cipher & decipher', function () {
|
||||||
@ -15,26 +15,21 @@ describe('CryptTool', function () {
|
|||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
async function (key, password, message) {
|
async function (key, password, message) {
|
||||||
const clean = jsdom();
|
// pause to let async functions conclude
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
|
let clean = jsdom();
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
global.btoa = common.btoa;
|
|
||||||
message = message.trim();
|
message = message.trim();
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
key, password, cipherMessage
|
key, password, cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
return message === plaintext;
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 3});
|
{tests: 3});
|
||||||
@ -43,19 +38,15 @@ describe('CryptTool', function () {
|
|||||||
// The below static unit tests are included to ensure deciphering of "classic"
|
// The below static unit tests are included to ensure deciphering of "classic"
|
||||||
// SJCL based pastes still works
|
// SJCL based pastes still works
|
||||||
it(
|
it(
|
||||||
'supports PrivateBin v1 ciphertext with password (SJCL & browser atob)',
|
'supports PrivateBin v1 ciphertext (SJCL & browser atob)',
|
||||||
async function () {
|
function () {
|
||||||
delete global.Base64;
|
delete global.Base64;
|
||||||
const clean = jsdom();
|
let clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
// Of course you can easily decipher the following texts, if you like.
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
// Bonus points for finding their sources and hidden meanings.
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
return $.PrivateBin.CryptTool.decipher(
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
// -- "That's amazing. I've got the same combination on my luggage."
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
||||||
@ -86,76 +77,53 @@ describe('CryptTool', function () {
|
|||||||
'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
|
'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
|
||||||
'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
|
'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
|
||||||
'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
|
'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
|
||||||
);
|
).then(function (paste1) {
|
||||||
clean();
|
$.PrivateBin.CryptTool.decipher(
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
||||||
if (!result) console.log(paste);
|
'', // no password
|
||||||
assert.ok(result);
|
'{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
|
||||||
}
|
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
||||||
);
|
'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
|
||||||
|
'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
|
||||||
it(
|
'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
|
||||||
'supports PrivateBin v1 ciphertext no password (SJCL & browser atob)',
|
'/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
|
||||||
async function () {
|
'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
|
||||||
delete global.Base64;
|
'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
|
||||||
const clean = jsdom();
|
'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
|
||||||
// ensure zlib is getting loaded
|
'+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
|
||||||
$.PrivateBin.Controller.initZ();
|
'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
|
||||||
Object.defineProperty(window, 'crypto', {
|
'24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
|
||||||
value: new WebCrypto(),
|
'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
|
||||||
writeable: false,
|
'8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
|
||||||
|
'//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
|
||||||
|
'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
|
||||||
|
'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
|
||||||
|
'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
|
||||||
|
'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
|
||||||
|
'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
|
||||||
|
'99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
|
||||||
|
'MZtmnYpGAtAPg7AUG"}'
|
||||||
|
).then(function (paste2) {
|
||||||
|
clean();
|
||||||
|
assert.ok(
|
||||||
|
paste1.includes('securely packed in iron') &&
|
||||||
|
paste2.includes('Sol is right')
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
|
|
||||||
'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
|
|
||||||
'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
|
|
||||||
'/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
|
|
||||||
'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
|
|
||||||
'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
|
|
||||||
'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
|
|
||||||
'+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
|
|
||||||
'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
|
|
||||||
'24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
|
|
||||||
'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
|
|
||||||
'8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
|
|
||||||
'//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
|
|
||||||
'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
|
|
||||||
'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
|
|
||||||
'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
|
|
||||||
'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
|
|
||||||
'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
|
|
||||||
'99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
|
|
||||||
'MZtmnYpGAtAPg7AUG"}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it(
|
it(
|
||||||
'supports ZeroBin ciphertext with password (SJCL & Base64 1.7)',
|
'supports ZeroBin ciphertext (SJCL & Base64 1.7)',
|
||||||
async function () {
|
function () {
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
global.Base64 = require('../base64-1.7').Base64;
|
||||||
const clean = jsdom();
|
var clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
// Of course you can easily decipher the following texts, if you like.
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
// Bonus points for finding their sources and hidden meanings.
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
return $.PrivateBin.CryptTool.decipher(
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
// -- "That's amazing. I've got the same combination on my luggage."
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
||||||
@ -178,74 +146,54 @@ describe('CryptTool', function () {
|
|||||||
'7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
|
'7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
|
||||||
'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
|
'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
|
||||||
'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
|
'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
|
||||||
);
|
).then(function (paste1) {
|
||||||
clean();
|
$.PrivateBin.CryptTool.decipher(
|
||||||
delete global.Base64;
|
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
'', // no password
|
||||||
if (!result) console.log(paste);
|
'{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
|
||||||
assert.ok(result);
|
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
||||||
}
|
'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
|
||||||
);
|
'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
|
||||||
|
'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
|
||||||
it(
|
'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
|
||||||
'supports ZeroBin ciphertext no password (SJCL & Base64 1.7)',
|
'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
|
||||||
async function () {
|
'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
|
||||||
const clean = jsdom();
|
'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
|
||||||
Object.defineProperty(window, 'crypto', {
|
'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
|
||||||
value: new WebCrypto(),
|
'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
|
||||||
writeable: false,
|
'7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
|
||||||
|
'7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
|
||||||
|
'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
|
||||||
|
).then(function (paste2) {
|
||||||
|
clean();
|
||||||
|
delete global.Base64;
|
||||||
|
assert.ok(
|
||||||
|
paste1.includes('securely packed in iron') &&
|
||||||
|
paste2.includes('Sol is right')
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
|
|
||||||
'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
|
|
||||||
'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
|
|
||||||
'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
|
|
||||||
'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
|
|
||||||
'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
|
|
||||||
'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
|
|
||||||
'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
|
|
||||||
'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
|
|
||||||
'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
|
|
||||||
'7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
|
|
||||||
'7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
|
|
||||||
'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
delete global.Base64;
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it('does not truncate messages', async function () {
|
it('does not truncate messages', async function () {
|
||||||
const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
|
let message = fs.readFileSync('test/compression-sample.txt', 'utf8'),
|
||||||
clean = jsdom();
|
clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
global.atob = common.atob;
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
global.btoa = common.btoa;
|
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
|
||||||
'foo', 'bar', message, []
|
'foo', 'bar', message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
'foo', 'bar', cipherMessage
|
'foo', 'bar', cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
assert.strictEqual(
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
message,
|
||||||
assert.ok(result);
|
plaintext
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can en- and decrypt a particular message (#260)', function () {
|
it('can en- and decrypt a particular message (#260)', function () {
|
||||||
@ -253,6 +201,8 @@ describe('CryptTool', function () {
|
|||||||
'string',
|
'string',
|
||||||
'string',
|
'string',
|
||||||
async function (key, password) {
|
async function (key, password) {
|
||||||
|
// pause to let async functions conclude
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
const message = `
|
const message = `
|
||||||
1 subgoal
|
1 subgoal
|
||||||
|
|
||||||
@ -275,23 +225,18 @@ isWhile : interp (while expr sBody) (MemElem mem) =
|
|||||||
======================== ( 1 / 1 )
|
======================== ( 1 / 1 )
|
||||||
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
||||||
`;
|
`;
|
||||||
const clean = jsdom();
|
let clean = jsdom();
|
||||||
// ensure zlib is getting loaded
|
// ensure zlib is getting loaded
|
||||||
$.PrivateBin.Controller.initZ();
|
$.PrivateBin.Controller.initZ();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
const cipherMessage = await $.PrivateBin.CryptTool.cipher(
|
|
||||||
key, password, message, []
|
key, password, message, []
|
||||||
),
|
),
|
||||||
plaintext = await $.PrivateBin.CryptTool.decipher(
|
plaintext = await $.PrivateBin.CryptTool.decipher(
|
||||||
key, password, cipherMessage
|
key, password, cipherMessage
|
||||||
);
|
);
|
||||||
clean();
|
clean();
|
||||||
const result = (message === plaintext);
|
return message === plaintext;
|
||||||
if (!result) console.log(plaintext, cipherMessage);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{tests: 3});
|
{tests: 3});
|
||||||
@ -299,27 +244,23 @@ conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('getSymmetricKey', function () {
|
describe('getSymmetricKey', function () {
|
||||||
this.timeout(10000);
|
this.timeout(30000);
|
||||||
let keys = [];
|
var keys = [];
|
||||||
|
|
||||||
// the parameter is used to ensure the test is run more then one time
|
// the parameter is used to ensure the test is run more then one time
|
||||||
it('returns random, non-empty keys', function () {
|
jsc.property(
|
||||||
jsc.assert(jsc.forall(
|
'returns random, non-empty keys',
|
||||||
'integer',
|
'integer',
|
||||||
function(counter) {
|
function(counter) {
|
||||||
const clean = jsdom();
|
var clean = jsdom();
|
||||||
Object.defineProperty(window, 'crypto', {
|
window.crypto = new WebCrypto();
|
||||||
value: new WebCrypto(),
|
var key = $.PrivateBin.CryptTool.getSymmetricKey(),
|
||||||
writeable: false,
|
result = (key !== '' && keys.indexOf(key) === -1);
|
||||||
});
|
keys.push(key);
|
||||||
const key = $.PrivateBin.CryptTool.getSymmetricKey(),
|
clean();
|
||||||
result = (key !== '' && keys.indexOf(key) === -1);
|
return result;
|
||||||
keys.push(key);
|
}
|
||||||
clean();
|
);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
),
|
|
||||||
{tests: 10});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -229,30 +229,30 @@ describe('Helper', function () {
|
|||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* TODO test fails since jsDOM version 17 - document.cookie remains empty
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the requested cookie',
|
'returns the requested cookie',
|
||||||
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
||||||
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
||||||
function (labels, values) {
|
function (labels, values) {
|
||||||
let selectedKey = '', selectedValue = '';
|
var selectedKey = '', selectedValue = '',
|
||||||
const clean = jsdom();
|
cookieArray = [];
|
||||||
labels.forEach(function(item, i) {
|
labels.forEach(function(item, i) {
|
||||||
const key = item.join(''),
|
var key = item.join(''),
|
||||||
value = (values[i] || values[0]).join('');
|
value = (values[i] || values[0]).join('');
|
||||||
document.cookie = key + '=' + value;
|
cookieArray.push(key + '=' + value);
|
||||||
if (Math.random() < 1 / i || selectedKey === key)
|
if (Math.random() < 1 / i || selectedKey === key)
|
||||||
{
|
{
|
||||||
selectedKey = key;
|
selectedKey = key;
|
||||||
selectedValue = value;
|
selectedValue = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const result = $.PrivateBin.Helper.getCookie(selectedKey);
|
var clean = jsdom('', {cookie: cookieArray}),
|
||||||
|
result = $.PrivateBin.Helper.getCookie(selectedKey);
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
clean();
|
clean();
|
||||||
return result === selectedValue;
|
return result === selectedValue;
|
||||||
}
|
}
|
||||||
); */
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('baseUri', function () {
|
describe('baseUri', function () {
|
||||||
|
@ -94,6 +94,7 @@ describe('Model', function () {
|
|||||||
url.query = queryStart.concat(pasteId, queryEnd);
|
url.query = queryStart.concat(pasteId, queryEnd);
|
||||||
const pasteIdString = pasteId.join(''),
|
const pasteIdString = pasteId.join(''),
|
||||||
clean = jsdom('', {url: common.urlToString(url)});
|
clean = jsdom('', {url: common.urlToString(url)});
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
const result = $.PrivateBin.Model.getPasteId();
|
const result = $.PrivateBin.Model.getPasteId();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
clean();
|
clean();
|
||||||
@ -106,6 +107,7 @@ describe('Model', function () {
|
|||||||
function (url) {
|
function (url) {
|
||||||
let clean = jsdom('', {url: common.urlToString(url)}),
|
let clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = false;
|
result = false;
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
try {
|
try {
|
||||||
$.PrivateBin.Model.getPasteId();
|
$.PrivateBin.Model.getPasteId();
|
||||||
}
|
}
|
||||||
@ -129,7 +131,7 @@ describe('Model', function () {
|
|||||||
'returns the fragment of a v1 URL',
|
'returns the fragment of a v1 URL',
|
||||||
common.jscUrl(),
|
common.jscUrl(),
|
||||||
function (url) {
|
function (url) {
|
||||||
url.fragment = '0OIl'; // any non-base58 string
|
url.fragment = common.btoa(url.fragment.padStart(32, '\u0000'));
|
||||||
const clean = jsdom('', {url: common.urlToString(url)}),
|
const clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = $.PrivateBin.Model.getPasteKey();
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
@ -138,17 +140,17 @@ describe('Model', function () {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the fragment stripped of trailing query parts',
|
'returns the v1 fragment stripped of trailing query parts',
|
||||||
common.jscUrl(),
|
common.jscUrl(),
|
||||||
jsc.array(common.jscHashString()),
|
jsc.array(common.jscHashString()),
|
||||||
function (url, trail) {
|
function (url, trail) {
|
||||||
const fragment = url.fragment.padStart(32, '\u0000');
|
const fragmentString = common.btoa(url.fragment.padStart(32, '\u0000'));
|
||||||
url.fragment = $.PrivateBin.CryptTool.base58encode(fragment) + '&' + trail.join('');
|
url.fragment = fragmentString + '&' + trail.join('');
|
||||||
const clean = jsdom('', {url: common.urlToString(url)}),
|
const clean = jsdom('', {url: common.urlToString(url)}),
|
||||||
result = $.PrivateBin.Model.getPasteKey();
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
clean();
|
clean();
|
||||||
return fragment === result;
|
return fragmentString === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
@ -11,7 +11,7 @@ describe('Prompt', function () {
|
|||||||
'returns the password fed into the dialog',
|
'returns the password fed into the dialog',
|
||||||
'string',
|
'string',
|
||||||
function (password) {
|
function (password) {
|
||||||
password = password.replace(/\r+|\n+/g, '');
|
password = password.replace(/\r+/g, '');
|
||||||
var clean = jsdom('', {url: 'ftp://example.com/?0000000000000000'});
|
var clean = jsdom('', {url: 'ftp://example.com/?0000000000000000'});
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<div id="passwordmodal" class="modal fade" role="dialog">' +
|
'<div id="passwordmodal" class="modal fade" role="dialog">' +
|
||||||
@ -32,8 +32,7 @@ describe('Prompt', function () {
|
|||||||
//var result = $.PrivateBin.Prompt.getPassword();
|
//var result = $.PrivateBin.Prompt.getPassword();
|
||||||
var result = $('#passworddecrypt').val();
|
var result = $('#passworddecrypt').val();
|
||||||
$.PrivateBin.Model.reset();
|
$.PrivateBin.Model.reset();
|
||||||
// TODO triggers error messages in jsDOM since version 11
|
clean();
|
||||||
//clean();
|
|
||||||
return result === password;
|
return result === password;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -621,7 +621,7 @@ describe('TopNav', function () {
|
|||||||
'returns the contents of the password input',
|
'returns the contents of the password input',
|
||||||
'string',
|
'string',
|
||||||
function (password) {
|
function (password) {
|
||||||
password = password.replace(/\r+|\n+/g, '');
|
password = password.replace(/\r+/g, '');
|
||||||
var results = [];
|
var results = [];
|
||||||
$('body').html(
|
$('body').html(
|
||||||
'<nav><div id="navbar"><ul><li><div id="password" ' +
|
'<nav><div id="navbar"><ul><li><div id="password" ' +
|
||||||
@ -727,11 +727,11 @@ describe('TopNav', function () {
|
|||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO triggers error messages in jsDOM since version 12, but passes
|
|
||||||
it(
|
it(
|
||||||
'displays raw text view correctly',
|
'displays raw text view correctly',
|
||||||
function () {
|
function () {
|
||||||
const clean = jsdom('', {url: 'https://privatebin.net/?0123456789abcdef#0'});
|
const clean = jsdom('', {url: 'https://privatebin.net/?0123456789abcdef#0'});
|
||||||
|
global.URL = require('jsdom-url').URL;
|
||||||
$('body').html('<button id="rawtextbutton"></button>');
|
$('body').html('<button id="rawtextbutton"></button>');
|
||||||
const sample = 'example';
|
const sample = 'example';
|
||||||
$.PrivateBin.PasteViewer.setText(sample);
|
$.PrivateBin.PasteViewer.setText(sample);
|
||||||
|
@ -18,6 +18,11 @@ describe('UiHelper', function () {
|
|||||||
const expected = common.urlToString(url),
|
const expected = common.urlToString(url),
|
||||||
clean = jsdom('', {url: expected});
|
clean = jsdom('', {url: expected});
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.mockHistoryChange();
|
$.PrivateBin.UiHelper.mockHistoryChange();
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
var result = window.location.href;
|
var result = window.location.href;
|
||||||
@ -35,6 +40,11 @@ describe('UiHelper', function () {
|
|||||||
const expected = common.urlToString(url),
|
const expected = common.urlToString(url),
|
||||||
clean = jsdom('', {url: expected});
|
clean = jsdom('', {url: expected});
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.mockHistoryChange([
|
$.PrivateBin.UiHelper.mockHistoryChange([
|
||||||
{type: 'newpaste'}, '', expected
|
{type: 'newpaste'}, '', expected
|
||||||
]);
|
]);
|
||||||
@ -47,8 +57,6 @@ describe('UiHelper', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('reloadHome', function () {
|
describe('reloadHome', function () {
|
||||||
// TODO triggers error messages in jsDOM since version 11
|
|
||||||
/*
|
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
before(function () {
|
before(function () {
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
@ -63,6 +71,11 @@ describe('UiHelper', function () {
|
|||||||
delete(url.fragment);
|
delete(url.fragment);
|
||||||
const expected = common.urlToString(url);
|
const expected = common.urlToString(url);
|
||||||
|
|
||||||
|
// make window.location.href writable
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
writable: true,
|
||||||
|
value: window.location.href
|
||||||
|
});
|
||||||
$.PrivateBin.UiHelper.reloadHome();
|
$.PrivateBin.UiHelper.reloadHome();
|
||||||
$.PrivateBin.Helper.reset();
|
$.PrivateBin.Helper.reset();
|
||||||
var result = window.location.href;
|
var result = window.location.href;
|
||||||
@ -70,7 +83,6 @@ describe('UiHelper', function () {
|
|||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isVisible', function () {
|
describe('isVisible', function () {
|
||||||
|
@ -45,18 +45,7 @@ class Configuration
|
|||||||
'defaultformatter' => 'plaintext',
|
'defaultformatter' => 'plaintext',
|
||||||
'syntaxhighlightingtheme' => '',
|
'syntaxhighlightingtheme' => '',
|
||||||
'sizelimit' => 10485760,
|
'sizelimit' => 10485760,
|
||||||
'templateselection' => false,
|
|
||||||
'template' => 'bootstrap',
|
'template' => 'bootstrap',
|
||||||
'availabletemplates' => array(
|
|
||||||
'bootstrap5',
|
|
||||||
'bootstrap',
|
|
||||||
'bootstrap-page',
|
|
||||||
'bootstrap-dark',
|
|
||||||
'bootstrap-dark-page',
|
|
||||||
'bootstrap-compact',
|
|
||||||
'bootstrap-compact-page',
|
|
||||||
'page',
|
|
||||||
),
|
|
||||||
'info' => 'More information on the <a href=\'https://privatebin.info/\'>project page</a>.',
|
'info' => 'More information on the <a href=\'https://privatebin.info/\'>project page</a>.',
|
||||||
'notice' => '',
|
'notice' => '',
|
||||||
'languageselection' => false,
|
'languageselection' => false,
|
||||||
@ -119,8 +108,8 @@ class Configuration
|
|||||||
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
||||||
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
||||||
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
||||||
'js/privatebin.js' => 'sha512-yN0ZaVFrXpiYaeFRcofdCrlHVcw4ZJAXU3K1l6H9rsoY//iLKegX0GdWxRCFWzhd1xO4eDJKCT7qyaA1Vt65bg==',
|
'js/privatebin.js' => 'sha512-POa+8KNXFFwJFsqp7r9APmR5Rc1w2l363y+OScSzLCySrHN7UhOOgt1VH/o8mVddFvvUozj3FZVmdkTxRlrS5g==',
|
||||||
'js/purify-3.2.5.js' => 'sha512-eLlLLL/zYuf5JuG0x4WQm687MToqOGP9cDQHIdmOy1ZpjiY4J48BBcOM7DtZheKk1UogW920+9RslWYB4KGuuA==',
|
'js/purify-3.2.4.js' => 'sha512-Mu9BqoHURMeycg6AgqTpokUv9guq88pajfaFqz53fx1OxohyROkydXPLEIbdKCQ7EdDs9hgcrYeZ9zTiPQQ4CA==',
|
||||||
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
|
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
|
||||||
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
||||||
'js/zlib-1.3.1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
'js/zlib-1.3.1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
||||||
|
@ -112,12 +112,10 @@ class Controller
|
|||||||
*
|
*
|
||||||
* initializes and runs PrivateBin
|
* initializes and runs PrivateBin
|
||||||
*
|
*
|
||||||
* @param ?Configuration $config
|
|
||||||
*
|
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(?Configuration $config = null)
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
|
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
|
||||||
error_log(I18n::_('%s requires php %s or above to work. Sorry.', I18n::_('PrivateBin'), self::MIN_PHP_VERSION));
|
error_log(I18n::_('%s requires php %s or above to work. Sorry.', I18n::_('PrivateBin'), self::MIN_PHP_VERSION));
|
||||||
@ -128,8 +126,7 @@ class Controller
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load config (using ini file by default) & initialize required classes
|
// load config from ini file, initialize required classes
|
||||||
$this->_conf = $config ?? new Configuration();
|
|
||||||
$this->_init();
|
$this->_init();
|
||||||
|
|
||||||
switch ($this->_request->getOperation()) {
|
switch ($this->_request->getOperation()) {
|
||||||
@ -177,21 +174,12 @@ class Controller
|
|||||||
*/
|
*/
|
||||||
private function _init()
|
private function _init()
|
||||||
{
|
{
|
||||||
|
$this->_conf = new Configuration;
|
||||||
$this->_model = new Model($this->_conf);
|
$this->_model = new Model($this->_conf);
|
||||||
$this->_request = new Request;
|
$this->_request = new Request;
|
||||||
$this->_urlBase = $this->_request->getRequestUri();
|
$this->_urlBase = $this->_request->getRequestUri();
|
||||||
|
|
||||||
$this->_setDefaultLanguage();
|
// set default language
|
||||||
$this->_setDefaultTemplate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default language
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _setDefaultLanguage()
|
|
||||||
{
|
|
||||||
$lang = $this->_conf->getKey('languagedefault');
|
$lang = $this->_conf->getKey('languagedefault');
|
||||||
I18n::setLanguageFallback($lang);
|
I18n::setLanguageFallback($lang);
|
||||||
// force default language, if language selection is disabled and a default is set
|
// force default language, if language selection is disabled and a default is set
|
||||||
@ -201,25 +189,6 @@ class Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default template
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private function _setDefaultTemplate()
|
|
||||||
{
|
|
||||||
$templates = $this->_conf->getKey('availabletemplates');
|
|
||||||
$template = $this->_conf->getKey('template');
|
|
||||||
TemplateSwitcher::setAvailableTemplates($templates);
|
|
||||||
TemplateSwitcher::setTemplateFallback($template);
|
|
||||||
|
|
||||||
// force default template, if template selection is disabled and a default is set
|
|
||||||
if (!$this->_conf->getKey('templateselection') && !empty($template)) {
|
|
||||||
$_COOKIE['template'] = $template;
|
|
||||||
setcookie('template', $template, array('SameSite' => 'Lax', 'Secure' => true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn off browser caching
|
* Turn off browser caching
|
||||||
*
|
*
|
||||||
@ -431,13 +400,6 @@ class Controller
|
|||||||
setcookie('lang', $languageselection, array('SameSite' => 'Lax', 'Secure' => true));
|
setcookie('lang', $languageselection, array('SameSite' => 'Lax', 'Secure' => true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set template cookie if that functionality was enabled
|
|
||||||
$templateselection = '';
|
|
||||||
if ($this->_conf->getKey('templateselection')) {
|
|
||||||
$templateselection = TemplateSwitcher::getTemplate();
|
|
||||||
setcookie('template', $templateselection, array('SameSite' => 'Lax', 'Secure' => true));
|
|
||||||
}
|
|
||||||
|
|
||||||
// strip policies that are unsupported in meta tag
|
// strip policies that are unsupported in meta tag
|
||||||
$metacspheader = str_replace(
|
$metacspheader = str_replace(
|
||||||
array(
|
array(
|
||||||
@ -476,8 +438,6 @@ class Controller
|
|||||||
$page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
|
$page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
|
||||||
$page->assign('LANGUAGESELECTION', $languageselection);
|
$page->assign('LANGUAGESELECTION', $languageselection);
|
||||||
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
||||||
$page->assign('TEMPLATESELECTION', $templateselection);
|
|
||||||
$page->assign('TEMPLATES', TemplateSwitcher::getAvailableTemplates());
|
|
||||||
$page->assign('EXPIRE', $expire);
|
$page->assign('EXPIRE', $expire);
|
||||||
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
|
$page->assign('EXPIREDEFAULT', $this->_conf->getKey('default', 'expire'));
|
||||||
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
$page->assign('URLSHORTENER', $this->_conf->getKey('urlshortener'));
|
||||||
@ -487,7 +447,7 @@ class Controller
|
|||||||
$page->assign('HTTPSLINK', 'https://' . $this->_request->getHost() . $this->_request->getRequestUri());
|
$page->assign('HTTPSLINK', 'https://' . $this->_request->getHost() . $this->_request->getRequestUri());
|
||||||
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
$page->assign('COMPRESSION', $this->_conf->getKey('compression'));
|
||||||
$page->assign('SRI', $this->_conf->getSection('sri'));
|
$page->assign('SRI', $this->_conf->getSection('sri'));
|
||||||
$page->draw(TemplateSwitcher::getTemplate());
|
$page->draw($this->_conf->getKey('template'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +34,7 @@ abstract class AbstractData
|
|||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
abstract public function create($pasteid, array &$paste);
|
abstract public function create($pasteid, array $paste);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a paste.
|
* Read a paste.
|
||||||
@ -72,7 +72,7 @@ abstract class AbstractData
|
|||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
abstract public function createComment($pasteid, $parentid, $commentid, array &$comment);
|
abstract public function createComment($pasteid, $parentid, $commentid, array $comment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all comments of paste.
|
* Read all comments of paste.
|
||||||
@ -199,7 +199,7 @@ abstract class AbstractData
|
|||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected static function upgradePreV1Format(array &$paste)
|
protected static function upgradePreV1Format(array $paste)
|
||||||
{
|
{
|
||||||
if (array_key_exists('attachment', $paste['meta'])) {
|
if (array_key_exists('attachment', $paste['meta'])) {
|
||||||
$paste['attachment'] = $paste['meta']['attachment'];
|
$paste['attachment'] = $paste['meta']['attachment'];
|
||||||
|
@ -140,7 +140,7 @@ class Database extends AbstractData
|
|||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
$expire_date = 0;
|
$expire_date = 0;
|
||||||
$opendiscussion = $burnafterreading = false;
|
$opendiscussion = $burnafterreading = false;
|
||||||
@ -297,18 +297,14 @@ class Database extends AbstractData
|
|||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if (array_key_exists('data', $comment)) {
|
if (array_key_exists('data', $comment)) {
|
||||||
$version = 1;
|
$version = 1;
|
||||||
$data = $comment['data'];
|
$data = $comment['data'];
|
||||||
} else {
|
} else {
|
||||||
try {
|
$version = 2;
|
||||||
$version = 2;
|
$data = Json::encode($comment);
|
||||||
$data = Json::encode($comment);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
list($createdKey, $iconKey) = $this->_getVersionedKeys($version);
|
list($createdKey, $iconKey) = $this->_getVersionedKeys($version);
|
||||||
$meta = $comment['meta'];
|
$meta = $comment['meta'];
|
||||||
|
@ -85,7 +85,7 @@ class Filesystem extends AbstractData
|
|||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
$storagedir = $this->_dataid2path($pasteid);
|
$storagedir = $this->_dataid2path($pasteid);
|
||||||
$file = $storagedir . $pasteid . '.php';
|
$file = $storagedir . $pasteid . '.php';
|
||||||
@ -188,7 +188,7 @@ class Filesystem extends AbstractData
|
|||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
$storagedir = $this->_dataid2discussionpath($pasteid);
|
$storagedir = $this->_dataid2discussionpath($pasteid);
|
||||||
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
|
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
|
||||||
@ -343,11 +343,12 @@ class Filesystem extends AbstractData
|
|||||||
*/
|
*/
|
||||||
private function _get($filename)
|
private function _get($filename)
|
||||||
{
|
{
|
||||||
$data = substr(
|
return Json::decode(
|
||||||
file_get_contents($filename),
|
substr(
|
||||||
strlen(self::PROTECTION_LINE . PHP_EOL)
|
file_get_contents($filename),
|
||||||
|
strlen(self::PROTECTION_LINE . PHP_EOL)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
return Json::decode($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,7 +105,7 @@ class GoogleCloudStorage extends AbstractData
|
|||||||
* @param $payload array to store
|
* @param $payload array to store
|
||||||
* @return bool true if successful, otherwise false.
|
* @return bool true if successful, otherwise false.
|
||||||
*/
|
*/
|
||||||
private function _upload($key, &$payload)
|
private function _upload($key, $payload)
|
||||||
{
|
{
|
||||||
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
||||||
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
||||||
@ -136,7 +136,7 @@ class GoogleCloudStorage extends AbstractData
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
if ($this->exists($pasteid)) {
|
if ($this->exists($pasteid)) {
|
||||||
return false;
|
return false;
|
||||||
@ -201,7 +201,7 @@ class GoogleCloudStorage extends AbstractData
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
||||||
return false;
|
return false;
|
||||||
@ -219,8 +219,7 @@ class GoogleCloudStorage extends AbstractData
|
|||||||
$prefix = $this->_getKey($pasteid) . '/discussion/';
|
$prefix = $this->_getKey($pasteid) . '/discussion/';
|
||||||
try {
|
try {
|
||||||
foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) {
|
foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) {
|
||||||
$data = $this->_bucket->object($key->name())->downloadAsString();
|
$comment = JSON::decode($this->_bucket->object($key->name())->downloadAsString());
|
||||||
$comment = Json::decode($data);
|
|
||||||
$comment['id'] = basename($key->name());
|
$comment['id'] = basename($key->name());
|
||||||
$slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
|
$slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
|
||||||
$comments[$slot] = $comment;
|
$comments[$slot] = $comment;
|
||||||
|
@ -165,7 +165,7 @@ class S3Storage extends AbstractData
|
|||||||
* @param $payload array to store
|
* @param $payload array to store
|
||||||
* @return bool true if successful, otherwise false.
|
* @return bool true if successful, otherwise false.
|
||||||
*/
|
*/
|
||||||
private function _upload($key, &$payload)
|
private function _upload($key, $payload)
|
||||||
{
|
{
|
||||||
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
$metadata = array_key_exists('meta', $payload) ? $payload['meta'] : array();
|
||||||
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
unset($metadata['attachment'], $metadata['attachmentname'], $metadata['salt']);
|
||||||
@ -191,7 +191,7 @@ class S3Storage extends AbstractData
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, array &$paste)
|
public function create($pasteid, array $paste)
|
||||||
{
|
{
|
||||||
if ($this->exists($pasteid)) {
|
if ($this->exists($pasteid)) {
|
||||||
return false;
|
return false;
|
||||||
@ -263,7 +263,7 @@ class S3Storage extends AbstractData
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, array &$comment)
|
public function createComment($pasteid, $parentid, $commentid, array $comment)
|
||||||
{
|
{
|
||||||
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
if ($this->existsComment($pasteid, $parentid, $commentid)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -29,7 +29,7 @@ class FormatV2
|
|||||||
* @param bool $isComment
|
* @param bool $isComment
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function isValid(&$message, $isComment = false)
|
public static function isValid($message, $isComment = false)
|
||||||
{
|
{
|
||||||
$required_keys = array('adata', 'v', 'ct');
|
$required_keys = array('adata', 'v', 'ct');
|
||||||
if ($isComment) {
|
if ($isComment) {
|
||||||
|
12
lib/I18n.php
@ -183,12 +183,9 @@ class I18n
|
|||||||
|
|
||||||
// load translations
|
// load translations
|
||||||
self::$_language = $match;
|
self::$_language = $match;
|
||||||
if ($match == 'en') {
|
self::$_translations = ($match == 'en') ? array() : Json::decode(
|
||||||
self::$_translations = array();
|
file_get_contents(self::_getPath($match . '.json'))
|
||||||
} else {
|
);
|
||||||
$data = file_get_contents(self::_getPath($match . '.json'));
|
|
||||||
self::$_translations = Json::decode($data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,8 +273,7 @@ class I18n
|
|||||||
{
|
{
|
||||||
$file = self::_getPath('languages.json');
|
$file = self::_getPath('languages.json');
|
||||||
if (count(self::$_languageLabels) == 0 && is_readable($file)) {
|
if (count(self::$_languageLabels) == 0 && is_readable($file)) {
|
||||||
$data = file_get_contents($file);
|
self::$_languageLabels = Json::decode(file_get_contents($file));
|
||||||
self::$_languageLabels = Json::decode($data);
|
|
||||||
}
|
}
|
||||||
if (count($languages) == 0) {
|
if (count($languages) == 0) {
|
||||||
return self::$_languageLabels;
|
return self::$_languageLabels;
|
||||||
|
@ -29,7 +29,7 @@ class Json
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function encode(&$input)
|
public static function encode($input)
|
||||||
{
|
{
|
||||||
$jsonString = json_encode($input);
|
$jsonString = json_encode($input);
|
||||||
self::_detectError();
|
self::_detectError();
|
||||||
@ -45,7 +45,7 @@ class Json
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function decode(&$input)
|
public static function decode($input)
|
||||||
{
|
{
|
||||||
$output = json_decode($input, true);
|
$output = json_decode($input, true);
|
||||||
self::_detectError();
|
self::_detectError();
|
||||||
|
@ -100,9 +100,9 @@ abstract class AbstractModel
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function setData(array &$data)
|
public function setData(array $data)
|
||||||
{
|
{
|
||||||
$this->_sanitize($data);
|
$data = $this->_sanitize($data);
|
||||||
$this->_validate($data);
|
$this->_validate($data);
|
||||||
$this->_data = $data;
|
$this->_data = $data;
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ abstract class AbstractModel
|
|||||||
*/
|
*/
|
||||||
public static function isValidId($id)
|
public static function isValidId($id)
|
||||||
{
|
{
|
||||||
return (bool) preg_match('#\A[a-f0-9]{16}\z#', (string) $id);
|
return (bool) preg_match('#\A[a-f\d]{16}\z#', (string) $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,8 +163,9 @@ abstract class AbstractModel
|
|||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
abstract protected function _sanitize(array &$data);
|
abstract protected function _sanitize(array $data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate data.
|
* Validate data.
|
||||||
@ -173,7 +174,7 @@ abstract class AbstractModel
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function _validate(array &$data)
|
protected function _validate(array $data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ class Comment extends AbstractModel
|
|||||||
* @param Paste $paste
|
* @param Paste $paste
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function setPaste(Paste &$paste)
|
public function setPaste(Paste $paste)
|
||||||
{
|
{
|
||||||
$this->_paste = $paste;
|
$this->_paste = $paste;
|
||||||
$this->_data['pasteid'] = $paste->getId();
|
$this->_data['pasteid'] = $paste->getId();
|
||||||
@ -155,8 +155,9 @@ class Comment extends AbstractModel
|
|||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function _sanitize(array &$data)
|
protected function _sanitize(array $data)
|
||||||
{
|
{
|
||||||
// we generate an icon based on a SHA512 HMAC of the users IP, if configured
|
// we generate an icon based on a SHA512 HMAC of the users IP, if configured
|
||||||
$icon = $this->_conf->getKey('icon');
|
$icon = $this->_conf->getKey('icon');
|
||||||
@ -189,5 +190,6 @@ class Comment extends AbstractModel
|
|||||||
$data['meta']['icon'] = $pngdata;
|
$data['meta']['icon'] = $pngdata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,10 +219,11 @@ class Paste extends AbstractModel
|
|||||||
*
|
*
|
||||||
* @access protected
|
* @access protected
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function _sanitize(array &$data)
|
protected function _sanitize(array $data)
|
||||||
{
|
{
|
||||||
$expiration = $data['meta']['expire'] ?? 0;
|
$expiration = $data['meta']['expire'];
|
||||||
unset($data['meta']['expire']);
|
unset($data['meta']['expire']);
|
||||||
$expire_options = $this->_conf->getSection('expire_options');
|
$expire_options = $this->_conf->getSection('expire_options');
|
||||||
if (array_key_exists($expiration, $expire_options)) {
|
if (array_key_exists($expiration, $expire_options)) {
|
||||||
@ -234,6 +235,7 @@ class Paste extends AbstractModel
|
|||||||
if ($expire > 0) {
|
if ($expire > 0) {
|
||||||
$data['meta']['expire_date'] = time() + $expire;
|
$data['meta']['expire_date'] = time() + $expire;
|
||||||
}
|
}
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,7 +245,7 @@ class Paste extends AbstractModel
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function _validate(array &$data)
|
protected function _validate(array $data)
|
||||||
{
|
{
|
||||||
// reject invalid or disabled formatters
|
// reject invalid or disabled formatters
|
||||||
if (!array_key_exists($data['adata'][1], $this->_conf->getSection('formatter_options'))) {
|
if (!array_key_exists($data['adata'][1], $this->_conf->getSection('formatter_options'))) {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
namespace PrivateBin;
|
namespace PrivateBin;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use PrivateBin\Model\Paste;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request
|
* Request
|
||||||
@ -85,7 +84,7 @@ class Request
|
|||||||
foreach ($_GET as $key => $value) {
|
foreach ($_GET as $key => $value) {
|
||||||
// only return if value is empty and key is 16 hex chars
|
// only return if value is empty and key is 16 hex chars
|
||||||
$key = (string) $key;
|
$key = (string) $key;
|
||||||
if (empty($value) && Paste::isValidId($key)) {
|
if (($value === '') && strlen($key) === 16 && ctype_xdigit($key)) {
|
||||||
return $key;
|
return $key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,8 +110,9 @@ class Request
|
|||||||
// it might be a creation or a deletion, the latter is detected below
|
// it might be a creation or a deletion, the latter is detected below
|
||||||
$this->_operation = 'create';
|
$this->_operation = 'create';
|
||||||
try {
|
try {
|
||||||
$data = file_get_contents(self::$_inputStream);
|
$this->_params = Json::decode(
|
||||||
$this->_params = Json::decode($data);
|
file_get_contents(self::$_inputStream)
|
||||||
|
);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// ignore error, $this->_params will remain empty
|
// ignore error, $this->_params will remain empty
|
||||||
}
|
}
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PrivateBin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TemplateSwitcher
|
|
||||||
*
|
|
||||||
* Provides tool to change application template
|
|
||||||
*/
|
|
||||||
class TemplateSwitcher
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* template fallback
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @static
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected static $_templateFallback;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* available templates
|
|
||||||
*
|
|
||||||
* @access protected
|
|
||||||
* @static
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected static $_availableTemplates = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set available templates
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @param array $templates
|
|
||||||
*/
|
|
||||||
public static function setAvailableTemplates(array $templates)
|
|
||||||
{
|
|
||||||
self::$_availableTemplates = $templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set the default template
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @param string $template
|
|
||||||
*/
|
|
||||||
public static function setTemplateFallback(string $template)
|
|
||||||
{
|
|
||||||
if (self::isTemplateAvailable($template)) {
|
|
||||||
self::$_templateFallback = $template;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get currently loaded template
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getTemplate(): string
|
|
||||||
{
|
|
||||||
$selectedTemplate = self::getSelectedByUserTemplate();
|
|
||||||
return $selectedTemplate ?? self::$_templateFallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get list of available templates
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getAvailableTemplates(): array
|
|
||||||
{
|
|
||||||
return self::$_availableTemplates;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the provided template is available
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isTemplateAvailable(string $template): bool
|
|
||||||
{
|
|
||||||
return in_array($template, self::getAvailableTemplates());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the template selected by user
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @static
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
private static function getSelectedByUserTemplate(): ?string
|
|
||||||
{
|
|
||||||
$selectedTemplate = null;
|
|
||||||
$templateCookieValue = $_COOKIE['template'] ?? '';
|
|
||||||
|
|
||||||
if (self::isTemplateAvailable($templateCookieValue)) {
|
|
||||||
$selectedTemplate = $templateCookieValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $selectedTemplate;
|
|
||||||
}
|
|
||||||
}
|
|
@ -70,7 +70,7 @@ class View
|
|||||||
$sri = array_key_exists($file, $this->_variables['SRI']) ?
|
$sri = array_key_exists($file, $this->_variables['SRI']) ?
|
||||||
' integrity="' . $this->_variables['SRI'][$file] . '"' : '';
|
' integrity="' . $this->_variables['SRI'][$file] . '"' : '';
|
||||||
// if the file isn't versioned (ends in a digit), add our own version
|
// if the file isn't versioned (ends in a digit), add our own version
|
||||||
$cacheBuster = (bool) preg_match('#[0-9]\.js$#', (string) $file) ?
|
$cacheBuster = ctype_digit(substr($file, -4, 1)) ?
|
||||||
'' : '?' . rawurlencode($this->_variables['VERSION']);
|
'' : '?' . rawurlencode($this->_variables['VERSION']);
|
||||||
echo '<script ', $attributes,
|
echo '<script ', $attributes,
|
||||||
' type="text/javascript" data-cfasync="false" src="', $file,
|
' type="text/javascript" data-cfasync="false" src="', $file,
|
||||||
|
@ -71,7 +71,7 @@ if ($MARKDOWN) :
|
|||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<?php $this->_scriptTag('js/purify-3.2.5.js', 'async'); ?>
|
<?php $this->_scriptTag('js/purify-3.2.4.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
@ -457,28 +457,6 @@ if (!empty($LANGUAGESELECTION)) :
|
|||||||
</li>
|
</li>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
if (!empty($TEMPLATESELECTION)) :
|
|
||||||
?>
|
|
||||||
<li id="template" class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo I18n::_('Theme'); ?>: <?php echo $TEMPLATESELECTION; ?> <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-right">
|
|
||||||
<?php
|
|
||||||
foreach ($TEMPLATES as $value) :
|
|
||||||
?>
|
|
||||||
<li>
|
|
||||||
<a href="#" data-template="<?php echo $value; ?>">
|
|
||||||
<?php echo $value; ?>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
endforeach;
|
|
||||||
?>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
?>
|
?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -575,8 +553,8 @@ if (!empty($URLSHORTENER)) :
|
|||||||
?>
|
?>
|
||||||
<p>
|
<p>
|
||||||
<button id="shortenbutton" data-shortener="<?php echo I18n::encode($URLSHORTENER); ?>" type="button" class="btn btn-<?php echo $isDark ? 'warning' : 'primary'; ?> btn-block">
|
<button id="shortenbutton" data-shortener="<?php echo I18n::encode($URLSHORTENER); ?>" type="button" class="btn btn-<?php echo $isDark ? 'warning' : 'primary'; ?> btn-block">
|
||||||
<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo I18n::_('Shorten URL'), PHP_EOL; ?>
|
<span class="glyphicon glyphicon-send" aria-hidden="true"></span> <?php echo I18n::_('Shorten URL'), PHP_EOL; ?>
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
<div role="alert" class="alert alert-danger">
|
<div role="alert" class="alert alert-danger">
|
||||||
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||||
|
@ -55,7 +55,7 @@ if ($MARKDOWN) :
|
|||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<?php $this->_scriptTag('js/purify-3.2.5.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/purify-3.2.4.js', 'defer'); ?>
|
||||||
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
@ -323,30 +323,6 @@ if (!empty($LANGUAGESELECTION)) :
|
|||||||
</li>
|
</li>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
if (!empty($TEMPLATESELECTION)) :
|
|
||||||
?>
|
|
||||||
<li id="template" class="nav-item dropdown">
|
|
||||||
<a href="#" class="nav-link dropdown-toggle d-flex align-items-center gap-1" data-bs-toggle="dropdown" role="button" aria-expanded="false">
|
|
||||||
<?php echo I18n::_('Theme'); ?>: <?php echo $TEMPLATESELECTION, PHP_EOL; ?>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-end" role="menu">
|
|
||||||
<?php
|
|
||||||
foreach ($TEMPLATES as $value) :
|
|
||||||
?>
|
|
||||||
<li>
|
|
||||||
<a href="#" class="dropdown-item" data-template="<?php echo $value; ?>">
|
|
||||||
<?php echo $value; ?>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
endforeach;
|
|
||||||
?>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
?>
|
?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -442,8 +418,8 @@ if (!empty($URLSHORTENER)) :
|
|||||||
?>
|
?>
|
||||||
<p>
|
<p>
|
||||||
<button id="shortenbutton" data-shortener="<?php echo I18n::encode($URLSHORTENER); ?>" type="button" class="btn btn-primary btn-block d-flex justify-content-center align-items-center gap-1">
|
<button id="shortenbutton" data-shortener="<?php echo I18n::encode($URLSHORTENER); ?>" type="button" class="btn btn-primary btn-block d-flex justify-content-center align-items-center gap-1">
|
||||||
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#send" /></svg> <?php echo I18n::_('Shorten URL'), PHP_EOL; ?>
|
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#send" /></svg> <?php echo I18n::_('Shorten URL'), PHP_EOL; ?>
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
<div role="alert" class="alert alert-danger">
|
<div role="alert" class="alert alert-danger">
|
||||||
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#exclamation-circle" /></svg>
|
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#exclamation-circle" /></svg>
|
||||||
|
23
tpl/page.php
@ -49,7 +49,7 @@ if ($MARKDOWN):
|
|||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<?php $this->_scriptTag('js/purify-3.2.5.js', 'async'); ?>
|
<?php $this->_scriptTag('js/purify-3.2.4.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
<?php $this->_scriptTag('js/legacy.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
|
||||||
<!-- icon -->
|
<!-- icon -->
|
||||||
@ -222,27 +222,6 @@ if (!empty($LANGUAGESELECTION)):
|
|||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
if (!empty($TEMPLATESELECTION)):
|
|
||||||
?>
|
|
||||||
<div id="template" class="button"><?php echo I18n::_('Theme'); ?>:
|
|
||||||
<select name="template">
|
|
||||||
<?php
|
|
||||||
foreach ($TEMPLATES as $value):
|
|
||||||
?>
|
|
||||||
<option data-template="<?php echo $value; ?>" value="<?php echo $value; ?>"<?php
|
|
||||||
if ($value == $TEMPLATESELECTION):
|
|
||||||
?> selected="selected"<?php
|
|
||||||
endif;
|
|
||||||
?>><?php echo $value; ?></option>
|
|
||||||
<?php
|
|
||||||
endforeach;
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
|
@ -823,11 +823,6 @@ class ConnectionInterfaceStub implements ConnectionInterface
|
|||||||
throw new BadMethodCallException('not supported by this stub');
|
throw new BadMethodCallException('not supported by this stub');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function moveObject(array $args = array())
|
|
||||||
{
|
|
||||||
throw new BadMethodCallException('not supported by this stub');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function composeObject(array $args = array())
|
public function composeObject(array $args = array())
|
||||||
{
|
{
|
||||||
throw new BadMethodCallException('not supported by this stub');
|
throw new BadMethodCallException('not supported by this stub');
|
||||||
|