mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2024-03-22 13:10:41 +08:00
Merge branch 'master' into js-unit-testing
This commit is contained in:
commit
57ebc7338d
18
.eslintrc
18
.eslintrc
|
@ -15,7 +15,9 @@ globals:
|
||||||
# http://eslint.org/docs/rules/
|
# http://eslint.org/docs/rules/
|
||||||
rules:
|
rules:
|
||||||
# Possible Errors
|
# Possible Errors
|
||||||
comma-dangle: [2, never]
|
comma-dangle:
|
||||||
|
- error
|
||||||
|
- never
|
||||||
no-cond-assign: 2
|
no-cond-assign: 2
|
||||||
no-console: 0
|
no-console: 0
|
||||||
no-constant-condition: 2
|
no-constant-condition: 2
|
||||||
|
@ -31,7 +33,9 @@ rules:
|
||||||
no-extra-parens: 0
|
no-extra-parens: 0
|
||||||
no-extra-semi: 2
|
no-extra-semi: 2
|
||||||
no-func-assign: 2
|
no-func-assign: 2
|
||||||
no-inner-declarations: [2, functions]
|
no-inner-declarations:
|
||||||
|
- error
|
||||||
|
- functions
|
||||||
no-invalid-regexp: 2
|
no-invalid-regexp: 2
|
||||||
no-irregular-whitespace: 2
|
no-irregular-whitespace: 2
|
||||||
no-negated-in-lhs: 2
|
no-negated-in-lhs: 2
|
||||||
|
@ -47,7 +51,9 @@ rules:
|
||||||
# Best Practices
|
# Best Practices
|
||||||
accessor-pairs: 2
|
accessor-pairs: 2
|
||||||
block-scoped-var: 0
|
block-scoped-var: 0
|
||||||
complexity: [2, 6]
|
complexity:
|
||||||
|
- error
|
||||||
|
- 20
|
||||||
consistent-return: 0
|
consistent-return: 0
|
||||||
curly: 0
|
curly: 0
|
||||||
default-case: 0
|
default-case: 0
|
||||||
|
@ -99,7 +105,7 @@ rules:
|
||||||
no-with: 2
|
no-with: 2
|
||||||
radix: 2
|
radix: 2
|
||||||
vars-on-top: 0
|
vars-on-top: 0
|
||||||
wrap-iife: 2
|
wrap-iife: 0
|
||||||
yoda: 0
|
yoda: 0
|
||||||
|
|
||||||
# Strict
|
# Strict
|
||||||
|
@ -152,7 +158,9 @@ rules:
|
||||||
max-len: 0
|
max-len: 0
|
||||||
max-nested-callbacks: 0
|
max-nested-callbacks: 0
|
||||||
max-params: 0
|
max-params: 0
|
||||||
max-statements: [2, 30]
|
max-statements:
|
||||||
|
- error
|
||||||
|
- 60
|
||||||
new-cap: 0
|
new-cap: 0
|
||||||
new-parens: 0
|
new-parens: 0
|
||||||
newline-after-var: 0
|
newline-after-var: 0
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
# Ignore server files for safety
|
# Ignore server files for safety
|
||||||
.htaccess
|
.htaccess
|
||||||
.htpasswd
|
.htpasswd
|
||||||
|
cfg/conf.ini
|
||||||
|
|
||||||
# Ignore data/
|
# Ignore data/
|
||||||
data/
|
data/
|
||||||
|
@ -30,6 +31,7 @@ vendor/**/build_phar.php
|
||||||
# Ignore local node modules, unit testing logs, api docs and eclipse project files
|
# Ignore local node modules, unit testing logs, api docs and eclipse project files
|
||||||
js/node_modules/
|
js/node_modules/
|
||||||
tst/log/
|
tst/log/
|
||||||
|
tst/ConfigurationCombinationsTest.php
|
||||||
.settings
|
.settings
|
||||||
.buildpath
|
.buildpath
|
||||||
.project
|
.project
|
||||||
|
|
|
@ -7,6 +7,7 @@ php:
|
||||||
- '7.0'
|
- '7.0'
|
||||||
- '7.1'
|
- '7.1'
|
||||||
|
|
||||||
|
# as this is a php project, node.js v4 (for JS unit testing) isn't installed
|
||||||
install:
|
install:
|
||||||
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 4
|
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 4
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ before_script:
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cd tst && phpunit
|
- cd tst && ../vendor/bin/phpunit
|
||||||
- cd ../js && mocha
|
- cd ../js && mocha
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# PrivateBin version history
|
# PrivateBin version history
|
||||||
|
|
||||||
* **next (not yet released)**
|
* **next (not yet released)**
|
||||||
* ADDED: Translations for Spanish, Occitan and Norwegian
|
* ADDED: Translations for Spanish, Occitan, Norwegian and Portuguese
|
||||||
* ADDED: Option in configuration to change the default "PrivateBin" title of the site
|
* ADDED: Option in configuration to change the default "PrivateBin" title of the site
|
||||||
|
* CHANGED: Minimum required PHP version is 5.4 (#186)
|
||||||
|
* CHANGED: Shipped .htaccess files were updated for Apache 2.4 (#192)
|
||||||
* CHANGED: Cleanup of bootstrap template variants and moved icons to `img` directory
|
* CHANGED: Cleanup of bootstrap template variants and moved icons to `img` directory
|
||||||
* **1.1 (2016-12-26)**
|
* **1.1 (2016-12-26)**
|
||||||
* ADDED: Translations for Italian and Russian
|
* ADDED: Translations for Italian and Russian
|
||||||
|
|
|
@ -35,3 +35,4 @@ Sébastien Sauvage - original idea and main developer
|
||||||
* Alfredo Fabián Altamirano Tena - Spanish
|
* Alfredo Fabián Altamirano Tena - Spanish
|
||||||
* Quent-in - Occitan
|
* Quent-in - Occitan
|
||||||
* idarlund - Norwegian
|
* idarlund - Norwegian
|
||||||
|
* Tulio Leao - Portuguese
|
||||||
|
|
|
@ -10,7 +10,7 @@ check the options and adjust them as you see fit.
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
- PHP version 5.3 or above
|
- PHP version 5.4 or above
|
||||||
- _one_ of the following sources of cryptographically safe randomness is required:
|
- _one_ of the following sources of cryptographically safe randomness is required:
|
||||||
- PHP 7 or higher
|
- PHP 7 or higher
|
||||||
- [Libsodium](https://download.libsodium.org/libsodium/content/installation/) and it's [PHP extension](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium)
|
- [Libsodium](https://download.libsodium.org/libsodium/content/installation/) and it's [PHP extension](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium)
|
||||||
|
|
|
@ -16,10 +16,10 @@ Data is encrypted/decrypted in the browser using 256bit AES in [Galois Counter m
|
||||||
|
|
||||||
This is a fork of ZeroBin, originally developed by
|
This is a fork of ZeroBin, originally developed by
|
||||||
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). It was refactored
|
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). It was refactored
|
||||||
to allow easier and cleaner extensions and has now much more features than the
|
to allow easier and cleaner extensions and has now many more features than the
|
||||||
original. It is however still fully compatible to the original ZeroBin 0.19
|
original. It is however still fully compatible to the original ZeroBin 0.19
|
||||||
data storage scheme. Therefore such installations can be upgraded to this fork
|
data storage scheme. Therefore such installations can be upgraded to this fork
|
||||||
without loosing any data.
|
without losing any data.
|
||||||
|
|
||||||
## What PrivateBin provides
|
## What PrivateBin provides
|
||||||
|
|
||||||
|
|
1
cfg/.gitignore
vendored
1
cfg/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/conf.ini
|
|
|
@ -1,2 +1 @@
|
||||||
Allow from none
|
Require all denied
|
||||||
Deny from all
|
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^5.3.0 || ^7.0",
|
"php": "^5.4.0 || ^7.0",
|
||||||
"paragonie/random_compat": "2.0.4",
|
"paragonie/random_compat": "2.0.4",
|
||||||
"yzalis/identicon": "1.1.0"
|
"yzalis/identicon": "1.1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"codacy/coverage": "dev-master",
|
"codacy/coverage": "dev-master",
|
||||||
"codeclimate/php-test-reporter": "dev-master"
|
"codeclimate/php-test-reporter": "dev-master",
|
||||||
|
"phpunit/phpunit": "^4.6 || ^5.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
|
@ -17,6 +17,10 @@ body.navbar-spacing {
|
||||||
padding-top: 70px;
|
padding-top: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.loading {
|
||||||
|
cursor: wait;
|
||||||
|
}
|
||||||
|
|
||||||
.buttondisabled {
|
.buttondisabled {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +106,12 @@ body.navbar-spacing {
|
||||||
border-left: 1px solid #ccc;
|
border-left: 1px solid #ccc;
|
||||||
padding: 5px 0 5px 10px;
|
padding: 5px 0 5px 10px;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
transition: background-color 0.75s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment.highlight {
|
||||||
|
background-color: #ffdd86;
|
||||||
|
transition: background-color 0.2s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer h4 {
|
footer h4 {
|
||||||
|
|
43
i18n/de.json
43
i18n/de.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "de",
|
"en": "de",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Diesen Text gibt es nicht, er ist abgelaufen oder wurde gelöscht.",
|
"Diesen Text gibt es nicht, er ist abgelaufen oder wurde gelöscht.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"%s benötigt PHP 5.3.0 oder höher, um zu funktionieren. Sorry.",
|
"%s benötigt PHP %s oder höher, um zu funktionieren. Sorry.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s benötigt den Konfigurationsabschnitt [%s] in der Konfigurationsdatei um zu funktionieren.",
|
"%s benötigt den Konfigurationsabschnitt [%s] in der Konfigurationsdatei um zu funktionieren.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -83,25 +83,25 @@
|
||||||
"Could not decrypt data (Wrong key?)":
|
"Could not decrypt data (Wrong key?)":
|
||||||
"Konnte Daten nicht entschlüsseln (Falscher Schlüssel?)",
|
"Konnte Daten nicht entschlüsseln (Falscher Schlüssel?)",
|
||||||
"Could not delete the paste, it was not stored in burn after reading mode.":
|
"Could not delete the paste, it was not stored in burn after reading mode.":
|
||||||
"Konnte den Text nicht löschen, er wurde nicht im Einmal-Modus gespeichert.",
|
"Konnte das Paste nicht löschen, es wurde nicht im Einmal-Modus gespeichert.",
|
||||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
|
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
|
||||||
"DIESER TEXT IST NUR FÜR DICH GEDACHT. Schliesse das Fenster nicht, diese Nachricht kann nur einmal geöffnet werden.",
|
"DIESER TEXT IST NUR FÜR DICH GEDACHT. Schließe das Fenster nicht, diese Nachricht kann nur einmal geöffnet werden.",
|
||||||
"Could not decrypt comment; Wrong key?":
|
"Could not decrypt comment; Wrong key?":
|
||||||
"Konnte Kommentar nicht entschlüsseln; Falscher Schlüssel?",
|
"Konnte Kommentar nicht entschlüsseln; Falscher Schlüssel?",
|
||||||
"Reply":
|
"Reply":
|
||||||
"Antworten",
|
"Antworten",
|
||||||
"Anonymous":
|
"Anonymous":
|
||||||
"Anonym",
|
"Anonym",
|
||||||
"Anonymous avatar (Vizhash of the IP address)":
|
"Avatar generated from IP address":
|
||||||
"Anonymer Avatar (Vizhash der IP-Addresse)",
|
"Avatar (generiert aus der IP-Adresse)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Kommentar hinzufügen",
|
"Kommentar hinzufügen",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Optionales Pseudonym...",
|
"Optionales Pseudonym…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Kommentar absenden",
|
"Kommentar absenden",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Sende Kommentar...",
|
"Sende Kommentar…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Kommentar gesendet.",
|
"Kommentar gesendet.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,24 +112,25 @@
|
||||||
"Fehler auf dem Server oder keine Antwort vom Server",
|
"Fehler auf dem Server oder keine Antwort vom Server",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Konnte Kommentar nicht senden: %s",
|
"Konnte Kommentar nicht senden: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Please move your mouse for more entropy…":
|
||||||
"Sende Text (Bitte bewege Deine Maus um die Entropie zu erhöhen)...",
|
"Bitte bewege Deine Maus um die Entropie zu erhöhen…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Sende Text...",
|
"Sende Paste…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Dein Text ist unter <a id=\"pasteurl\" href=\"%s\">%s</a> zu finden <span id=\"copyhint\">(Drücke [Strg]+[c] um den Link zu kopieren)</span>",
|
"Dein Paste ist unter <a id=\"pasteurl\" href=\"%s\">%s</a> zu finden <span id=\"copyhint\">(Drücke [Strg]+[c] um den Link zu kopieren)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
"Lösche Daten",
|
"Lösche Daten",
|
||||||
"Could not create paste: %s":
|
"Could not create paste: %s":
|
||||||
"Konnte Text nicht erstellen: %s",
|
"Konnte Paste nicht erstellen: %s",
|
||||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)":
|
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)":
|
||||||
"Konnte Text nicht entschlüsseln: Der Schlüssel fehlt in der Adresse (Hast du eine Umleitung oder einen URL-Verkürzer benutzt, der Teile der Adresse entfernt?)",
|
"Konnte Paste nicht entschlüsseln: Der Schlüssel fehlt in der Adresse (Hast du eine Umleitung oder einen URL-Verkürzer benutzt, der Teile der Adresse entfernt?)",
|
||||||
"Format": "Format",
|
"Format": "Format",
|
||||||
"Plain Text": "Nur Text",
|
"Plain Text": "Nur Text",
|
||||||
"Source Code": "Quellcode",
|
"Source Code": "Quellcode",
|
||||||
"Markdown": "Markdown",
|
"Markdown": "Markdown",
|
||||||
"Download attachment": "Anhang herunterladen",
|
"Download attachment": "Anhang herunterladen",
|
||||||
"Cloned file attached.": "Kopierte Datei angehängt.",
|
"Cloned: '%s'": "Geklont: '%s'",
|
||||||
|
"The cloned file '%s' was attached to this paste.": "Die geklonte Datei '%s' wurde angehängt.",
|
||||||
"Attach a file": "Datei anhängen",
|
"Attach a file": "Datei anhängen",
|
||||||
"Remove attachment": "Anhang entfernen",
|
"Remove attachment": "Anhang entfernen",
|
||||||
"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.":
|
||||||
|
@ -146,6 +147,10 @@
|
||||||
"Enter password":
|
"Enter password":
|
||||||
"Passwort eingeben",
|
"Passwort eingeben",
|
||||||
"Loading…": "Lädt…",
|
"Loading…": "Lädt…",
|
||||||
|
"Decrypting paste…": "Entschlüssle Paste…",
|
||||||
|
"Preparing new paste…": "Bereite neues Paste vor…",
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
"Wenn diese Nachricht nicht mehr verschwindet, schau bitte in <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">die FAQ</a> (englisch), um zu sehen, wie der Fehler behoben werden kann."
|
"Wenn diese Nachricht nicht mehr verschwindet, schau bitte in <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">die FAQ</a> (englisch), um zu sehen, wie der Fehler behoben werden kann.",
|
||||||
|
"+++ no paste text +++":
|
||||||
|
"+++ kein Paste-Text +++"
|
||||||
}
|
}
|
||||||
|
|
22
i18n/es.json
22
i18n/es.json
|
@ -7,10 +7,10 @@
|
||||||
"en": "es",
|
"en": "es",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"El texto no existe, ha caducado o ha sido eliminado.",
|
"El texto no existe, ha caducado o ha sido eliminado.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"%s requiere php 5.3.0 o superior para funcionar. Lo siento.",
|
"%s requiere php %s o superior para funcionar. Lo siento.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s requiere que la sección de configuración [% s] esté presente en el archivo de configuración.",
|
"%s requiere que la sección de configuración [%s] esté presente en el archivo de configuración.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
"Por favor espere %d segundos entre cada publicación.",
|
"Por favor espere %d segundos entre cada publicación.",
|
||||||
"Paste is limited to %s of encrypted data.":
|
"Paste is limited to %s of encrypted data.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Avatar anónimo (Vizhash de la dirección IP)",
|
"Avatar anónimo (Vizhash de la dirección IP)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Añadir comentario",
|
"Añadir comentario",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Seudónimo opcional...",
|
"Seudónimo opcional…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Publicar comentario",
|
"Publicar comentario",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Enviando comentario...",
|
"Enviando comentario…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Comentario publicado.",
|
"Comentario publicado.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"Error del servidor o el servidor no responde",
|
"Error del servidor o el servidor no responde",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"No fue posible publicar comentario: %s",
|
"No fue posible publicar comentario: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Enviando texto (Por favor, mueva el ratón para mayor entropía)...",
|
"Enviando texto (Por favor, mueva el ratón para mayor entropía)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Enviando texto...",
|
"Enviando texto…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Su texto está en <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Presione [Ctrl]+[c] para copiar)</span>",
|
"Su texto está en <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Presione [Ctrl]+[c] para copiar)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
|
28
i18n/fr.json
28
i18n/fr.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "fr",
|
"en": "fr",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Le paste n'existe pas, a expiré, ou a été supprimé.",
|
"Le paste n'existe pas, a expiré, ou a été supprimé.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"Désolé, %s nécessite php 5.3.0 ou supérieur pour fonctionner.",
|
"Désolé, %s nécessite php %s ou supérieur pour fonctionner.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s a besoin de la section de configuration [%s] dans le fichier de configuration pour fonctionner.",
|
"%s a besoin de la section de configuration [%s] dans le fichier de configuration pour fonctionner.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Avatar anonyme (Vizhash de l'adresse IP)",
|
"Avatar anonyme (Vizhash de l'adresse IP)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Ajouter un commentaire",
|
"Ajouter un commentaire",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Pseudonyme optionnel...",
|
"Pseudonyme optionnel…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Poster le commentaire",
|
"Poster le commentaire",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Envoi du commentaire...",
|
"Envoi du commentaire…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Commentaire posté.",
|
"Commentaire posté.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"Le serveur ne répond pas ou a rencontré une erreur",
|
"Le serveur ne répond pas ou a rencontré une erreur",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Impossible de poster le commentaire : %s",
|
"Impossible de poster le commentaire : %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Envoi du paste (Merci de bouger votre souris pour plus d'entropie)...",
|
"Envoi du paste (Merci de bouger votre souris pour plus d'entropie)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Envoi du paste...",
|
"Envoi du paste…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur [Ctrl]+[c] pour copier)</span>",
|
"Votre paste est disponible à l'adresse <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Appuyez sur [Ctrl]+[c] pour copier)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
@ -149,12 +149,12 @@
|
||||||
"Editor": "Éditer",
|
"Editor": "Éditer",
|
||||||
"Preview": "Prévisualiser",
|
"Preview": "Prévisualiser",
|
||||||
"%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.":
|
||||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
"%s requiert que le PATH se termine dans un \"%s\". Veuillez mettre à jour le PATH dans votre index.php.",
|
||||||
"Decrypt":
|
"Decrypt":
|
||||||
"Decrypt",
|
"Déchiffrer",
|
||||||
"Enter password":
|
"Enter password":
|
||||||
"Entrez le mot de passe",
|
"Entrez le mot de passe",
|
||||||
"Loading…": "Loading…",
|
"Loading…": "Chargement…",
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a> (in English)."
|
"Si ce message ne disparaîssait pas, jetez un oeil à <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">cette FAQ pour des idées de résolution</a> (en Anglais)."
|
||||||
}
|
}
|
||||||
|
|
28
i18n/it.json
28
i18n/it.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "it",
|
"en": "it",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Questo messaggio non esiste, è scaduto o è stato cancellato.",
|
"Questo messaggio non esiste, è scaduto o è stato cancellato.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"%s richiede PHP 5.3.0 o superiore.",
|
"%s richiede php %s o superiore per funzionare. Ci spiace.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s richiede la presenza della sezione [%s] nei file di configurazione.",
|
"%s richiede la presenza della sezione [%s] nei file di configurazione.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
"Never":
|
"Never":
|
||||||
"Mai",
|
"Mai",
|
||||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.":
|
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.":
|
||||||
"Nota: questo è un servizio di prova, i dati possono essere cancellati in qualsiasi momento. Ti preghiamo di non abusare di questo servizio, grazie.",
|
"Nota: questo è un servizio di prova, i messaggi salvati possono essere cancellati in qualsiasi momento. Moriranno dei gattini se abuserai di questo servizio.",
|
||||||
"This document will expire in %d seconds.":
|
"This document will expire in %d seconds.":
|
||||||
["Questo documento scadrà tra un secondo.", "Questo documento scadrà in %d secondi."],
|
["Questo documento scadrà tra un secondo.", "Questo documento scadrà in %d secondi."],
|
||||||
"This document will expire in %d minutes.":
|
"This document will expire in %d minutes.":
|
||||||
|
@ -87,21 +87,21 @@
|
||||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
|
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
|
||||||
"FOR YOUR EYES ONLY. Non chiudere questa finestra, il messaggio non può essere visualizzato una seconda volta.",
|
"FOR YOUR EYES ONLY. Non chiudere questa finestra, il messaggio non può essere visualizzato una seconda volta.",
|
||||||
"Could not decrypt comment; Wrong key?":
|
"Could not decrypt comment; Wrong key?":
|
||||||
"Non riesco a decifrari il commento (Chiave errata?)",
|
"Non riesco a decifrare il commento (Chiave errata?)",
|
||||||
"Reply":
|
"Reply":
|
||||||
"Rispondi",
|
"Rispondi",
|
||||||
"Anonymous":
|
"Anonymous":
|
||||||
"Anonimo",
|
"Anonimo",
|
||||||
"Anonymous avatar (Vizhash of the IP address)":
|
"Anonymous avatar (Vizhash of the IP address)":
|
||||||
"Avatar Anonino (Vizhash dell'indirizzo IP)",
|
"Avatar Anonimo (Vizhash dell'indirizzo IP)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Aggiungi un commento",
|
"Aggiungi un commento",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Nickname opzionale...",
|
"Nickname opzionale…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Invia commento",
|
"Invia commento",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Commento in fase di invio...",
|
"Commento in fase di invio…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Commento inviato.",
|
"Commento inviato.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"errore o mancata risposta dal server",
|
"errore o mancata risposta dal server",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Impossibile inviare il commento: %s",
|
"Impossibile inviare il commento: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Invio messaggio (Muovi il mouse in modo casuale, per generare maggior entropia)...",
|
"Invio messaggio (Muovi il mouse in modo casuale, per generare maggior entropia)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Messaggio in fase di invio...",
|
"Messaggio in fase di invio…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Il tuo messaggio è qui: <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">([CTRL | CMD]+[C] per copiare il link)</span>",
|
"Il tuo messaggio è qui: <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">([CTRL | CMD]+[C] per copiare il link)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
@ -147,5 +147,5 @@
|
||||||
"Inserisci la password",
|
"Inserisci la password",
|
||||||
"Loading…": "Loading…",
|
"Loading…": "Loading…",
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a> (in English)."
|
"Nel caso questo messaggio non scompaia, controlla questa <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\"> FAQ</a> per trovare informazioni su come risolvere il problema (in Inglese)."
|
||||||
}
|
}
|
||||||
|
|
20
i18n/no.json
20
i18n/no.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "no",
|
"en": "no",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Innlegget eksisterer ikke, er utløpt eller har blitt slettet.",
|
"Innlegget eksisterer ikke, er utløpt eller har blitt slettet.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"Beklager, %s krever php 5.3.0 eller nyere for å kjøre.",
|
"Beklager, %s krever php %s eller nyere for å kjøre.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s krever konfigurasjonsdel [%s] å være til stede i konfigurasjonsfilen .",
|
"%s krever konfigurasjonsdel [%s] å være til stede i konfigurasjonsfilen .",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Anonym avatar (Vizhash av IP adressen)",
|
"Anonym avatar (Vizhash av IP adressen)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Legg til kommentar",
|
"Legg til kommentar",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Valgfritt kallenavn...",
|
"Valgfritt kallenavn…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Send kommentar",
|
"Send kommentar",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Sender Kommentar...",
|
"Sender Kommentar…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Kommentar sendt.",
|
"Kommentar sendt.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"server feilet eller svarer ikke",
|
"server feilet eller svarer ikke",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Kunne ikke sende kommentar: %s",
|
"Kunne ikke sende kommentar: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Sender innlegg (Flytt musen for mere entropi)...",
|
"Sender innlegg (Flytt musen for mere entropi)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Sender innlegg...",
|
"Sender innlegg…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Ditt innlegg er <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Trykk [Ctrl]+[c] for å kopiere)</span>",
|
"Ditt innlegg er <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Trykk [Ctrl]+[c] for å kopiere)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
|
20
i18n/oc.json
20
i18n/oc.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "oc",
|
"en": "oc",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Lo tèxte existís pas, a expirat, o es estat suprimit.",
|
"Lo tèxte existís pas, a expirat, o es estat suprimit.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"O planhèm, %s necessita php 5.3.0 o superior per foncionar.",
|
"O planhèm, %s necessita php %s o superior per foncionar.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s fa besonh de la seccion de configuracion [%s] dins lo fichièr de configuracion per foncionar.",
|
"%s fa besonh de la seccion de configuracion [%s] dins lo fichièr de configuracion per foncionar.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Avatar anonime (Vizhash de l'adreça IP)",
|
"Avatar anonime (Vizhash de l'adreça IP)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Apondre un comentari",
|
"Apondre un comentari",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Escais opcional...",
|
"Escais opcional…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Mandar lo comentari",
|
"Mandar lo comentari",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Mandadís del comentari...",
|
"Mandadís del comentari…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Comentari mandat.",
|
"Comentari mandat.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"Lo servidor respond pas o a rencontrat una error",
|
"Lo servidor respond pas o a rencontrat una error",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Impossible de mandar lo comentari : %s",
|
"Impossible de mandar lo comentari : %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Mandadís del tèxte (Mercés de bolegar vòstra mirga per mai entropia)...",
|
"Mandadís del tèxte (Mercés de bolegar vòstra mirga per mai entropia)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Mandadís del tèxte...",
|
"Mandadís del tèxte…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Vòstre tèxte es disponible a l'adreça <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Picatz sus [Ctrl]+[c] per copiar)</span>",
|
"Vòstre tèxte es disponible a l'adreça <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Picatz sus [Ctrl]+[c] per copiar)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
|
20
i18n/pl.json
20
i18n/pl.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "pl",
|
"en": "pl",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Wklejka nie istnieje, wygasła albo została usunięta.",
|
"Wklejka nie istnieje, wygasła albo została usunięta.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"%s wymaga PHP w wersji 5.3.0 lub nowszej, sorry.",
|
"%s wymaga PHP w wersji %s lub nowszej, sorry.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s wymaga obecności sekcji [%s] w pliku konfiguracyjnym.",
|
"%s wymaga obecności sekcji [%s] w pliku konfiguracyjnym.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Anonimowy avatar (Vizhash z adresu IP)",
|
"Anonimowy avatar (Vizhash z adresu IP)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Dodaj komentarz",
|
"Dodaj komentarz",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Opcjonalny nick...",
|
"Opcjonalny nick…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Wyślij komentarz",
|
"Wyślij komentarz",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Wysyłanie komentarza...",
|
"Wysyłanie komentarza…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Wysłano komentarz.",
|
"Wysłano komentarz.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"bląd serwera lub brak odpowiedzi",
|
"bląd serwera lub brak odpowiedzi",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Nie udało się wysłać komentarza: %s",
|
"Nie udało się wysłać komentarza: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Wysyłanie wklejki (proszę poruszać myszą aby uzyskać większą entropię)...",
|
"Wysyłanie wklejki (proszę poruszać myszą aby uzyskać większą entropię)…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Wysyłanie wklejki...",
|
"Wysyłanie wklejki…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Twoja wklejka to <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(wciśnij [Ctrl]+[c] aby skopiować)</span>",
|
"Twoja wklejka to <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(wciśnij [Ctrl]+[c] aby skopiować)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
|
151
i18n/pt.json
Normal file
151
i18n/pt.json
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
{
|
||||||
|
"PrivateBin": "PrivateBin",
|
||||||
|
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted <i>in the browser</i> using 256 bits AES. More information on the <a href=\"https://privatebin.info/\">project page</a>.":
|
||||||
|
"%s é um serviço minimalista e de código aberto do tipo \"pastebin\", em que o servidor tem zero conhecimento dos dados copiados. Os dados são cifrados e decifrados <i>no navegador</i> usando 256 bits AES. Mais informações na <a href=\"https://privatebin.info/\">página do projeto</a>.",
|
||||||
|
"Because ignorance is bliss":
|
||||||
|
"Porque a ignorância é uma benção",
|
||||||
|
"en": "pt",
|
||||||
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
|
"A cópia não existe, expirou ou já foi excluída.",
|
||||||
|
"%s requires php %s or above to work. Sorry.":
|
||||||
|
"%s requer php %s ou superior para funcionar. Desculpa.",
|
||||||
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
|
"%s requer que a seção de configuração [% s] esteja no arquivo de configuração.",
|
||||||
|
"Please wait %d seconds between each post.":
|
||||||
|
"Por favor espere %d segundos entre cada publicação.",
|
||||||
|
"Paste is limited to %s of encrypted data.":
|
||||||
|
"A cópia está limitada a %s de dados cifrados.",
|
||||||
|
"Invalid data.":
|
||||||
|
"Dados inválidos.",
|
||||||
|
"You are unlucky. Try again.":
|
||||||
|
"Você é azarado. Tente novamente",
|
||||||
|
"Error saving comment. Sorry.":
|
||||||
|
"Erro ao salvar comentário. Desculpa.",
|
||||||
|
"Error saving paste. Sorry.":
|
||||||
|
"Erro ao salvar cópia. Desculpa.",
|
||||||
|
"Invalid paste ID.":
|
||||||
|
"ID de cópia inválido.",
|
||||||
|
"Paste is not of burn-after-reading type.":
|
||||||
|
"Cópia não é do tipo \"queime após ler\".",
|
||||||
|
"Wrong deletion token. Paste was not deleted.":
|
||||||
|
"Token de remoção inválido. A cópia não foi excluída.",
|
||||||
|
"Paste was properly deleted.":
|
||||||
|
"A cópia foi devidamente excluída.",
|
||||||
|
"JavaScript is required for %s to work.<br />Sorry for the inconvenience.":
|
||||||
|
"JavaScript é necessário para que %s funcione.<br />Pedimos desculpas pela inconveniência.",
|
||||||
|
"%s requires a modern browser to work.":
|
||||||
|
"%s requer um navegador moderno para funcionar.",
|
||||||
|
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
||||||
|
"Ainda usando Internet Explorer? Faça-se um favor, mude para um navegador moderno:",
|
||||||
|
"New":
|
||||||
|
"Novo",
|
||||||
|
"Send":
|
||||||
|
"Enviar",
|
||||||
|
"Clone":
|
||||||
|
"Clonar",
|
||||||
|
"Raw text":
|
||||||
|
"Texto sem formato",
|
||||||
|
"Expires":
|
||||||
|
"Expirar em",
|
||||||
|
"Burn after reading":
|
||||||
|
"Queime após ler",
|
||||||
|
"Open discussion":
|
||||||
|
"Discussão aberta",
|
||||||
|
"Password (recommended)":
|
||||||
|
"Senha (recomendada)",
|
||||||
|
"Discussion":
|
||||||
|
"Discussão",
|
||||||
|
"Toggle navigation":
|
||||||
|
"Mudar navegação",
|
||||||
|
"%d seconds": ["%d segundo", "%d segundos"],
|
||||||
|
"%d minutes": ["%d minuto", "%d minutos"],
|
||||||
|
"%d hours": ["%d hora", "%d horas"],
|
||||||
|
"%d days": ["%d dia", "%d dias"],
|
||||||
|
"%d weeks": ["%d semana", "%d semanas"],
|
||||||
|
"%d months": ["%d mês", "%d meses"],
|
||||||
|
"%d years": ["%d ano", "%d anos"],
|
||||||
|
"Never":
|
||||||
|
"Nunca",
|
||||||
|
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.":
|
||||||
|
"Nota: Este é um serviço de teste. Dados podem ser perdidos a qualquer momento. Gatinhos morrerão se você abusar desse serviço.",
|
||||||
|
"This document will expire in %d seconds.":
|
||||||
|
["Este documento irá expirar em um segundo.", "Este documento irá expirar em %d segundos."],
|
||||||
|
"This document will expire in %d minutes.":
|
||||||
|
["Este documento irá expirar em um minuto.", "Este documento irá expirar em %d minutos."],
|
||||||
|
"This document will expire in %d hours.":
|
||||||
|
["Este documento irá expirar em uma hora.", "Este documento irá expirar em %d horas."],
|
||||||
|
"This document will expire in %d days.":
|
||||||
|
["Este documento irá expirar em um dia.", "Este documento irá expirar em %d dias."],
|
||||||
|
"This document will expire in %d months.":
|
||||||
|
["Este documento irá expirar em um mês.", "Este documento irá expirar em %d meses."],
|
||||||
|
"Please enter the password for this paste:":
|
||||||
|
"Por favor, digite a senha para essa cópia:",
|
||||||
|
"Could not decrypt data (Wrong key?)":
|
||||||
|
"Não foi possível decifrar os dados (Chave errada?)",
|
||||||
|
"Could not delete the paste, it was not stored in burn after reading mode.":
|
||||||
|
"Não foi possível excluir a cópia, ela não foi salva no modo de \"queime após ler\".",
|
||||||
|
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.":
|
||||||
|
"APENAS PARA SEUS OLHOS. Não feche essa janela, essa mensagem não pode ser exibida novamente.",
|
||||||
|
"Could not decrypt comment; Wrong key?":
|
||||||
|
"Não foi possível decifrar o comentário; Chave errada?",
|
||||||
|
"Reply":
|
||||||
|
"Responder",
|
||||||
|
"Anonymous":
|
||||||
|
"Anônimo",
|
||||||
|
"Avatar generated from IP address":
|
||||||
|
"Avatar gerado à partir do endereço IP",
|
||||||
|
"Add comment":
|
||||||
|
"Adicionar comentário",
|
||||||
|
"Optional nickname…":
|
||||||
|
"Apelido opcional…",
|
||||||
|
"Post comment":
|
||||||
|
"Publicar comentário",
|
||||||
|
"Sending comment…":
|
||||||
|
"Enviando comentário…",
|
||||||
|
"Comment posted.":
|
||||||
|
"Comentário publicado.",
|
||||||
|
"Could not refresh display: %s":
|
||||||
|
"Não foi possível atualizar a tela: %s",
|
||||||
|
"unknown status":
|
||||||
|
"Estado desconhecido",
|
||||||
|
"server error or not responding":
|
||||||
|
"Servidor em erro ou não responsivo",
|
||||||
|
"Could not post comment: %s":
|
||||||
|
"Não foi possível publicar o comentário: %s",
|
||||||
|
"Please move your mouse for more entropy…":
|
||||||
|
"Por favor, mova o mouse para maior entropia…",
|
||||||
|
"Sending paste…":
|
||||||
|
"Enviando cópia…",
|
||||||
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
|
"Sua cópia é <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Pressione [Ctrl]+[c] para copiar)</span>",
|
||||||
|
"Delete data":
|
||||||
|
"Excluir dados",
|
||||||
|
"Could not create paste: %s":
|
||||||
|
"Não foi possível criar cópia: %s",
|
||||||
|
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)":
|
||||||
|
"Não foi possível decifrar a cópia: chave de decriptografia ausente na URL (Você utilizou um redirecionador ou encurtador de URL que removeu parte dela?)",
|
||||||
|
"Format": "Formato",
|
||||||
|
"Plain Text": "Texto sem formato",
|
||||||
|
"Source Code": "Código fonte",
|
||||||
|
"Markdown": "Markdown",
|
||||||
|
"Download attachment": "Baixar anexo",
|
||||||
|
"Cloned: '%s'": "Clonado: '%s'",
|
||||||
|
"Attach a file": "Anexar um arquivo",
|
||||||
|
"Remove attachment": "Remover anexo",
|
||||||
|
"Your browser does not support uploading encrypted files. Please use a newer browser.":
|
||||||
|
"Seu navegador não permite subir arquivos cifrados. Por favor, utilize um navegador mais recente.",
|
||||||
|
"Invalid attachment.": "Anexo inválido.",
|
||||||
|
"Options": "Opções",
|
||||||
|
"Shorten URL": "Encurtar URL",
|
||||||
|
"Editor": "Editor",
|
||||||
|
"Preview": "Visualizar",
|
||||||
|
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.":
|
||||||
|
"%s requer que o PATH termine em \"%s\". Por favor, atualize o PATH em seu index.php.",
|
||||||
|
"Decrypt":
|
||||||
|
"Decifrar",
|
||||||
|
"Enter password":
|
||||||
|
"Digite a senha",
|
||||||
|
"Loading…": "Carregando…",
|
||||||
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
|
"Caso essa mensagem nunca desapareça, por favor veja <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">este FAQ para saber como resolver os problemas</a>."
|
||||||
|
}
|
40
i18n/ru.json
40
i18n/ru.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "ru",
|
"en": "ru",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Запись не существует, просрочена или была удалена.",
|
"Запись не существует, просрочена или была удалена.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"Для работы %s требуется PHP 5.3.0 или выше. Извините.",
|
"Для работы %s требуется php %s или выше. Извините.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s необходимо наличие секции [%s] в конфигурационном файле.",
|
"%s необходимо наличие секции [%s] в конфигурационном файле.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
"Paste was properly deleted.":
|
"Paste was properly deleted.":
|
||||||
"Запись была успешно удалена.",
|
"Запись была успешно удалена.",
|
||||||
"JavaScript is required for %s to work.<br />Sorry for the inconvenience.":
|
"JavaScript is required for %s to work.<br />Sorry for the inconvenience.":
|
||||||
"Для работы %s требуется включенный JavaScript.<br />Приносим извинения за неудобства..",
|
"Для работы %s требуется включенный JavaScript.<br />Приносим извинения за неудобства.",
|
||||||
"%s requires a modern browser to work.":
|
"%s requires a modern browser to work.":
|
||||||
"Для работы %s требуется более современный браузер.",
|
"Для работы %s требуется более современный браузер.",
|
||||||
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
"Still using Internet Explorer? Do yourself a favor, switch to a modern browser:":
|
||||||
|
@ -96,26 +96,26 @@
|
||||||
"Анонимный аватар (Vizhash IP адреса)",
|
"Анонимный аватар (Vizhash IP адреса)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Добавить комментарий",
|
"Добавить комментарий",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Опциональный никнейм...",
|
"Опциональный никнейм…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Отправить комментарий",
|
"Отправить комментарий",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Отправка комментария...",
|
"Отправка комментария…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Комментарий опубликован.",
|
"Комментарий опубликован.",
|
||||||
"Could not refresh display: %s":
|
|
||||||
"Невозможно обновить данные: %s",
|
|
||||||
"unknown status":
|
"unknown status":
|
||||||
"неизвестная причина",
|
"неизвестная причина",
|
||||||
"server error or not responding":
|
"server error or not responding":
|
||||||
"ошибка сервера или нет ответа",
|
"ошибка сервера или нет ответа",
|
||||||
|
"unknown error":
|
||||||
|
"неизвестная ошибка",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Не удалось опубликовать комментарий: %s",
|
"Не удалось опубликовать комментарий: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Please move your mouse for more entropy…":
|
||||||
"Отправка записи (Пожалуйста двигайте мышкой для большей энтропии)...",
|
"Пожалуйста двигайте мышкой для большей энтропии…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Отправка записи...",
|
"Отправка записи…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Ссылка на запись <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Нажмите [Ctrl]+[c] чтобы скопировать ссылку)</span>",
|
"Ссылка на запись <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Нажмите [Ctrl]+[c] чтобы скопировать ссылку)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
@ -138,7 +138,10 @@
|
||||||
"Source Code": "Исходный код",
|
"Source Code": "Исходный код",
|
||||||
"Markdown": "Язык разметки",
|
"Markdown": "Язык разметки",
|
||||||
"Download attachment": "Скачать прикрепленный файл",
|
"Download attachment": "Скачать прикрепленный файл",
|
||||||
"Cloned file attached.": "Дубль файла прикреплен.",
|
"Cloned file attached.": "Дубликат файла прикреплен.",
|
||||||
|
"Cloned: '%s'": "Дублировано: '%s'",
|
||||||
|
"The cloned file '%s' was attached to this paste.":
|
||||||
|
"Дубликат файла '%s' был прикреплен к этой записи.",
|
||||||
"Attach a file": "Прикрепить файл",
|
"Attach a file": "Прикрепить файл",
|
||||||
"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.":
|
||||||
|
@ -155,5 +158,12 @@
|
||||||
"Enter password":
|
"Enter password":
|
||||||
"Введите пароль",
|
"Введите пароль",
|
||||||
"Uploading paste… Please wait.":
|
"Uploading paste… Please wait.":
|
||||||
"Отправка записи... Пожалуйста подождите."
|
"Отправка записи… Пожалуйста подождите.",
|
||||||
|
"Loading…": "Загрузка…",
|
||||||
|
"Decrypting paste…": "Расшифровка записи…",
|
||||||
|
"Preparing new paste…": "Подготовка новой записи…",
|
||||||
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
|
"Если данное сообщение не исчезает длительное время, посмотрите <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">этот FAQ с информацией о возможном решении проблемы (на английском)</a>.",
|
||||||
|
"+++ no paste text +++":
|
||||||
|
"+++ в записи нет текста +++"
|
||||||
}
|
}
|
||||||
|
|
18
i18n/sl.json
18
i18n/sl.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "sl",
|
"en": "sl",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"Prilepek ne obstaja, mu je potekla življenjska doba, ali pa je izbrisan.",
|
"Prilepek ne obstaja, mu je potekla življenjska doba, ali pa je izbrisan.",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"Oprosti, %s za delovanje potrebuje vsaj php 5.3.0.",
|
"Oprosti, %s za delovanje potrebuje vsaj php %s.",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s potrebuje sekcijo konfiguracij [%s] v konfiguracijski datoteki.",
|
"%s potrebuje sekcijo konfiguracij [%s] v konfiguracijski datoteki.",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -96,12 +96,12 @@
|
||||||
"Anonimen avatar (Vizhash IP naslova)",
|
"Anonimen avatar (Vizhash IP naslova)",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"Dodaj komentar",
|
"Dodaj komentar",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"Uporabniško ime (lahko izpustiš)",
|
"Uporabniško ime (lahko izpustiš)",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"Objavi komentar",
|
"Objavi komentar",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"Pošiljam komentar ...",
|
"Pošiljam komentar …",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"Komentar poslan.",
|
"Komentar poslan.",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"napaka na strežniku, ali pa se strežnik ne odziva",
|
"napaka na strežniku, ali pa se strežnik ne odziva",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"Komentarja ni bilo mogoče objaviti : %s",
|
"Komentarja ni bilo mogoče objaviti : %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Sending paste (Please move your mouse for more entropy)…":
|
||||||
"Pošiljam prilepek (prosim premakni svojo miško za več entropije) ...",
|
"Pošiljam prilepek (prosim premakni svojo miško za več entropije) …",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"Pošiljam prilepek...",
|
"Pošiljam prilepek…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"Tvoj prilepek je dostopen na naslovu: <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Pritisni [Ctrl]+[c] ali [Cmd] + [c] in skopiraj)</span>",
|
"Tvoj prilepek je dostopen na naslovu: <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Pritisni [Ctrl]+[c] ali [Cmd] + [c] in skopiraj)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
|
44
i18n/zh.json
44
i18n/zh.json
|
@ -7,8 +7,8 @@
|
||||||
"en": "zh",
|
"en": "zh",
|
||||||
"Paste does not exist, has expired or has been deleted.":
|
"Paste does not exist, has expired or has been deleted.":
|
||||||
"粘贴不存在,已过期或者已被删除。",
|
"粘贴不存在,已过期或者已被删除。",
|
||||||
"%s requires php 5.3.0 or above to work. Sorry.":
|
"%s requires php %s or above to work. Sorry.":
|
||||||
"%s需要工作于PHP 5.3.0及以上版本,抱歉。",
|
"%s需要工作于PHP %s及以上版本,抱歉。",
|
||||||
"%s requires configuration section [%s] to be present in configuration file.":
|
"%s requires configuration section [%s] to be present in configuration file.":
|
||||||
"%s需要设置配置文件中 [%s] 的部分。",
|
"%s需要设置配置文件中 [%s] 的部分。",
|
||||||
"Please wait %d seconds between each post.":
|
"Please wait %d seconds between each post.":
|
||||||
|
@ -92,16 +92,16 @@
|
||||||
"回复",
|
"回复",
|
||||||
"Anonymous":
|
"Anonymous":
|
||||||
"匿名",
|
"匿名",
|
||||||
"Anonymous avatar (Vizhash of the IP address)":
|
"Avatar generated from IP address":
|
||||||
"匿名头像 (由IP地址生成Vizhash)",
|
"由IP生成的头像",
|
||||||
"Add comment":
|
"Add comment":
|
||||||
"添加评论",
|
"添加评论",
|
||||||
"Optional nickname...":
|
"Optional nickname…":
|
||||||
"可选昵称...",
|
"可选昵称…",
|
||||||
"Post comment":
|
"Post comment":
|
||||||
"评论",
|
"评论",
|
||||||
"Sending comment...":
|
"Sending comment…":
|
||||||
"评论发送中...",
|
"评论发送中…",
|
||||||
"Comment posted.":
|
"Comment posted.":
|
||||||
"评论已发送。",
|
"评论已发送。",
|
||||||
"Could not refresh display: %s":
|
"Could not refresh display: %s":
|
||||||
|
@ -112,10 +112,10 @@
|
||||||
"服务器错误或无回应",
|
"服务器错误或无回应",
|
||||||
"Could not post comment: %s":
|
"Could not post comment: %s":
|
||||||
"无法发送评论: %s",
|
"无法发送评论: %s",
|
||||||
"Sending paste (Please move your mouse for more entropy)...":
|
"Please move your mouse for more entropy…":
|
||||||
"粘贴提交中 (请移动鼠标以产生更多熵)...",
|
"请移动鼠标增加随机性…",
|
||||||
"Sending paste...":
|
"Sending paste…":
|
||||||
"粘贴提交中...",
|
"粘贴提交中…",
|
||||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
|
||||||
"您的粘贴的链接是<a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(按下 [Ctrl]+[c] 以复制)</span>",
|
"您的粘贴的链接是<a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(按下 [Ctrl]+[c] 以复制)</span>",
|
||||||
"Delete data":
|
"Delete data":
|
||||||
|
@ -129,7 +129,8 @@
|
||||||
"Source Code": "源代码",
|
"Source Code": "源代码",
|
||||||
"Markdown": "Markdown",
|
"Markdown": "Markdown",
|
||||||
"Download attachment": "下载附件",
|
"Download attachment": "下载附件",
|
||||||
"Cloned file attached.": "已附加克隆的文件",
|
"Cloned: '%s'": "克隆: '%s'",
|
||||||
|
"The cloned file '%s' was attached to this paste.": "克隆文件 '%s' 已附加到此粘贴。",
|
||||||
"Attach a file": "添加一个附件",
|
"Attach a file": "添加一个附件",
|
||||||
"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.":
|
||||||
|
@ -137,15 +138,18 @@
|
||||||
"Invalid attachment.": "无效的附件",
|
"Invalid attachment.": "无效的附件",
|
||||||
"Options": "选项",
|
"Options": "选项",
|
||||||
"Shorten URL": "缩短链接",
|
"Shorten URL": "缩短链接",
|
||||||
"Editor": "編輯",
|
"Editor": "编辑",
|
||||||
"Preview": "預習",
|
"Preview": "预览",
|
||||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.":
|
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.":
|
||||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
"%s 的 PATH 变量必须结束于 \"%s\"。 请修改你的 index.php 中的 PATH 变量。",
|
||||||
"Decrypt":
|
"Decrypt":
|
||||||
"Decrypt",
|
"解密",
|
||||||
"Enter password":
|
"Enter password":
|
||||||
"Enter password",
|
"输入密码",
|
||||||
"Loading…": "Loading…",
|
"Loading…": "载入中…",
|
||||||
|
"Decrypting paste…": "正在解密",
|
||||||
|
"Preparing new paste…": "正在准备新的粘贴",
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a>.":
|
||||||
"In case this message never disappears please have a look at <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">this FAQ for information to troubleshoot</a> (in English)."
|
"如果这个消息一直不消失,请参考 <a href=\"https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away\">这里的 FAQ 进行故障排除</a> (英文版)。",
|
||||||
|
"+++ no paste text +++": "+++ 没有粘贴内容 +++"
|
||||||
}
|
}
|
||||||
|
|
4858
js/privatebin.js
4858
js/privatebin.js
File diff suppressed because it is too large
Load Diff
257
js/test.js
257
js/test.js
|
@ -11,7 +11,9 @@ var jsc = require('jsverify'),
|
||||||
a2zString.map(function(c) {
|
a2zString.map(function(c) {
|
||||||
return c.toUpperCase();
|
return c.toUpperCase();
|
||||||
})
|
})
|
||||||
);
|
),
|
||||||
|
// schemas supported by the whatwg-url library
|
||||||
|
schemas = ['ftp','gopher','http','https','ws','wss'];
|
||||||
|
|
||||||
global.$ = global.jQuery = require('./jquery-3.1.1');
|
global.$ = global.jQuery = require('./jquery-3.1.1');
|
||||||
global.sjcl = require('./sjcl-1.0.6');
|
global.sjcl = require('./sjcl-1.0.6');
|
||||||
|
@ -20,49 +22,49 @@ global.RawDeflate = require('./rawdeflate-0.5');
|
||||||
require('./rawinflate-0.3');
|
require('./rawinflate-0.3');
|
||||||
require('./privatebin');
|
require('./privatebin');
|
||||||
|
|
||||||
describe('helper', function () {
|
describe('Helper', function () {
|
||||||
describe('secondsToHuman', function () {
|
describe('secondsToHuman', function () {
|
||||||
after(function () {
|
after(function () {
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
jsc.property('returns an array with a number and a word', 'integer', function (number) {
|
jsc.property('returns an array with a number and a word', 'integer', function (number) {
|
||||||
var result = $.PrivateBin.helper.secondsToHuman(number);
|
var result = $.PrivateBin.Helper.secondsToHuman(number);
|
||||||
return Array.isArray(result) &&
|
return Array.isArray(result) &&
|
||||||
result.length === 2 &&
|
result.length === 2 &&
|
||||||
result[0] === parseInt(result[0], 10) &&
|
result[0] === parseInt(result[0], 10) &&
|
||||||
typeof result[1] === 'string';
|
typeof result[1] === 'string';
|
||||||
});
|
});
|
||||||
jsc.property('returns seconds on the first array position', 'integer 59', function (number) {
|
jsc.property('returns seconds on the first array position', 'integer 59', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[0] === number;
|
return $.PrivateBin.Helper.secondsToHuman(number)[0] === number;
|
||||||
});
|
});
|
||||||
jsc.property('returns seconds on the second array position', 'integer 59', function (number) {
|
jsc.property('returns seconds on the second array position', 'integer 59', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[1] === 'second';
|
return $.PrivateBin.Helper.secondsToHuman(number)[1] === 'second';
|
||||||
});
|
});
|
||||||
jsc.property('returns minutes on the first array position', 'integer 60 3599', function (number) {
|
jsc.property('returns minutes on the first array position', 'integer 60 3599', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[0] === Math.floor(number / 60);
|
return $.PrivateBin.Helper.secondsToHuman(number)[0] === Math.floor(number / 60);
|
||||||
});
|
});
|
||||||
jsc.property('returns minutes on the second array position', 'integer 60 3599', function (number) {
|
jsc.property('returns minutes on the second array position', 'integer 60 3599', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[1] === 'minute';
|
return $.PrivateBin.Helper.secondsToHuman(number)[1] === 'minute';
|
||||||
});
|
});
|
||||||
jsc.property('returns hours on the first array position', 'integer 3600 86399', function (number) {
|
jsc.property('returns hours on the first array position', 'integer 3600 86399', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60));
|
return $.PrivateBin.Helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60));
|
||||||
});
|
});
|
||||||
jsc.property('returns hours on the second array position', 'integer 3600 86399', function (number) {
|
jsc.property('returns hours on the second array position', 'integer 3600 86399', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[1] === 'hour';
|
return $.PrivateBin.Helper.secondsToHuman(number)[1] === 'hour';
|
||||||
});
|
});
|
||||||
jsc.property('returns days on the first array position', 'integer 86400 5184000', function (number) {
|
jsc.property('returns days on the first array position', 'integer 86400 5184000', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60 * 24));
|
return $.PrivateBin.Helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60 * 24));
|
||||||
});
|
});
|
||||||
jsc.property('returns days on the second array position', 'integer 86400 5184000', function (number) {
|
jsc.property('returns days on the second array position', 'integer 86400 5184000', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[1] === 'day';
|
return $.PrivateBin.Helper.secondsToHuman(number)[1] === 'day';
|
||||||
});
|
});
|
||||||
// max safe integer as per http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
|
// max safe integer as per http://ecma262-5.com/ELS5_HTML.htm#Section_8.5
|
||||||
jsc.property('returns months on the first array position', 'integer 5184000 9007199254740991', function (number) {
|
jsc.property('returns months on the first array position', 'integer 5184000 9007199254740991', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60 * 24 * 30));
|
return $.PrivateBin.Helper.secondsToHuman(number)[0] === Math.floor(number / (60 * 60 * 24 * 30));
|
||||||
});
|
});
|
||||||
jsc.property('returns months on the second array position', 'integer 5184000 9007199254740991', function (number) {
|
jsc.property('returns months on the second array position', 'integer 5184000 9007199254740991', function (number) {
|
||||||
return $.PrivateBin.helper.secondsToHuman(number)[1] === 'month';
|
return $.PrivateBin.Helper.secondsToHuman(number)[1] === 'month';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -77,11 +79,11 @@ describe('helper', function () {
|
||||||
var html = '',
|
var html = '',
|
||||||
result = true;
|
result = true;
|
||||||
ids.forEach(function(item, i) {
|
ids.forEach(function(item, i) {
|
||||||
html += '<div id="' + item.join('') + '">' + $.PrivateBin.helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
html += '<div id="' + item.join('') + '">' + $.PrivateBin.Helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
||||||
});
|
});
|
||||||
var clean = jsdom(html);
|
var clean = jsdom(html);
|
||||||
ids.forEach(function(item, i) {
|
ids.forEach(function(item, i) {
|
||||||
$.PrivateBin.helper.selectText(item.join(''));
|
$.PrivateBin.Helper.selectText(item.join(''));
|
||||||
// TODO: As per https://github.com/tmpvar/jsdom/issues/321 there is no getSelection in jsdom, yet.
|
// TODO: As per https://github.com/tmpvar/jsdom/issues/321 there is no getSelection in jsdom, yet.
|
||||||
// Once there is one, uncomment the line below to actually check the result.
|
// Once there is one, uncomment the line below to actually check the result.
|
||||||
//result *= (contents[i] || contents[0]) === window.getSelection().toString();
|
//result *= (contents[i] || contents[0]) === window.getSelection().toString();
|
||||||
|
@ -106,13 +108,13 @@ describe('helper', function () {
|
||||||
var html = '',
|
var html = '',
|
||||||
result = true;
|
result = true;
|
||||||
ids.forEach(function(item, i) {
|
ids.forEach(function(item, i) {
|
||||||
html += '<div id="' + item.join('') + '">' + $.PrivateBin.helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
html += '<div id="' + item.join('') + '">' + $.PrivateBin.Helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
||||||
});
|
});
|
||||||
var elements = $('<body />').html(html);
|
var elements = $('<body />').html(html);
|
||||||
ids.forEach(function(item, i) {
|
ids.forEach(function(item, i) {
|
||||||
var id = item.join(''),
|
var id = item.join(''),
|
||||||
element = elements.find('#' + id).first();
|
element = elements.find('#' + id).first();
|
||||||
$.PrivateBin.helper.setElementText(element, replacingContent);
|
$.PrivateBin.Helper.setElementText(element, replacingContent);
|
||||||
result *= replacingContent === element.text();
|
result *= replacingContent === element.text();
|
||||||
});
|
});
|
||||||
return Boolean(result);
|
return Boolean(result);
|
||||||
|
@ -120,56 +122,6 @@ describe('helper', function () {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setMessage', function () {
|
|
||||||
after(function () {
|
|
||||||
cleanup();
|
|
||||||
});
|
|
||||||
|
|
||||||
jsc.property(
|
|
||||||
'replaces the content of an empty element, analog to setElementText',
|
|
||||||
jsc.nearray(jsc.nearray(jsc.elements(alnumString))),
|
|
||||||
'nearray string',
|
|
||||||
'string',
|
|
||||||
function (ids, contents, replacingContent) {
|
|
||||||
var html = '',
|
|
||||||
result = true;
|
|
||||||
ids.forEach(function(item, i) {
|
|
||||||
html += '<div id="' + item.join('') + '">' + $.PrivateBin.helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
|
||||||
});
|
|
||||||
var elements = $('<body />').html(html);
|
|
||||||
ids.forEach(function(item, i) {
|
|
||||||
var id = item.join(''),
|
|
||||||
element = elements.find('#' + id).first();
|
|
||||||
$.PrivateBin.helper.setMessage(element, replacingContent);
|
|
||||||
result *= replacingContent === element.text();
|
|
||||||
});
|
|
||||||
return Boolean(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jsc.property(
|
|
||||||
'replaces the last child of a non-empty element',
|
|
||||||
jsc.nearray(jsc.nearray(jsc.elements(alnumString))),
|
|
||||||
jsc.nearray(jsc.nearray(jsc.elements(alnumString))),
|
|
||||||
'nearray string',
|
|
||||||
'string',
|
|
||||||
function (ids, classes, contents, replacingContent) {
|
|
||||||
var html = '',
|
|
||||||
result = true;
|
|
||||||
ids.forEach(function(item, i) {
|
|
||||||
html += '<div id="' + item.join('') + '"><span class="' + (classes[i] || classes[0]) + '"></span> ' + $.PrivateBin.helper.htmlEntities(contents[i] || contents[0]) + '</div>';
|
|
||||||
});
|
|
||||||
var elements = $('<body />').html(html);
|
|
||||||
ids.forEach(function(item, i) {
|
|
||||||
var id = item.join(''),
|
|
||||||
element = elements.find('#' + id).first();
|
|
||||||
$.PrivateBin.helper.setMessage(element, replacingContent);
|
|
||||||
result *= ' ' + replacingContent === element.contents()[1].nodeValue;
|
|
||||||
});
|
|
||||||
return Boolean(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('urls2links', function () {
|
describe('urls2links', function () {
|
||||||
after(function () {
|
after(function () {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
@ -181,7 +133,7 @@ describe('helper', function () {
|
||||||
function (content) {
|
function (content) {
|
||||||
var element = $('<div>' + content + '</div>'),
|
var element = $('<div>' + content + '</div>'),
|
||||||
before = element.html();
|
before = element.html();
|
||||||
$.PrivateBin.helper.urls2links(element);
|
$.PrivateBin.Helper.urls2links(element);
|
||||||
return before === element.html();
|
return before === element.html();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -197,8 +149,8 @@ describe('helper', function () {
|
||||||
var query = query.join(''),
|
var query = query.join(''),
|
||||||
fragment = fragment.join(''),
|
fragment = fragment.join(''),
|
||||||
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment,
|
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment,
|
||||||
prefix = $.PrivateBin.helper.htmlEntities(prefix),
|
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
|
||||||
postfix = ' ' + $.PrivateBin.helper.htmlEntities(postfix),
|
postfix = ' ' + $.PrivateBin.Helper.htmlEntities(postfix),
|
||||||
element = $('<div>' + prefix + url + postfix + '</div>');
|
element = $('<div>' + prefix + url + postfix + '</div>');
|
||||||
|
|
||||||
// special cases: When the query string and fragment imply the beginning of an HTML entity, eg. � or &#x
|
// special cases: When the query string and fragment imply the beginning of an HTML entity, eg. � or &#x
|
||||||
|
@ -212,7 +164,7 @@ describe('helper', function () {
|
||||||
element = $('<div>' + prefix + url + '</div>');
|
element = $('<div>' + prefix + url + '</div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$.PrivateBin.helper.urls2links(element);
|
$.PrivateBin.Helper.urls2links(element);
|
||||||
return element.html() === $('<div>' + prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a>' + postfix + '</div>').html();
|
return element.html() === $('<div>' + prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a>' + postfix + '</div>').html();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -223,10 +175,10 @@ describe('helper', function () {
|
||||||
'string',
|
'string',
|
||||||
function (prefix, query, postfix) {
|
function (prefix, query, postfix) {
|
||||||
var url = 'magnet:?' + query.join(''),
|
var url = 'magnet:?' + query.join(''),
|
||||||
prefix = $.PrivateBin.helper.htmlEntities(prefix),
|
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
|
||||||
postfix = $.PrivateBin.helper.htmlEntities(postfix),
|
postfix = $.PrivateBin.Helper.htmlEntities(postfix),
|
||||||
element = $('<div>' + prefix + url + ' ' + postfix + '</div>');
|
element = $('<div>' + prefix + url + ' ' + postfix + '</div>');
|
||||||
$.PrivateBin.helper.urls2links(element);
|
$.PrivateBin.Helper.urls2links(element);
|
||||||
return element.html() === $('<div>' + prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a> ' + postfix + '</div>').html();
|
return element.html() === $('<div>' + prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a> ' + postfix + '</div>').html();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -247,8 +199,7 @@ describe('helper', function () {
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
||||||
result = prefix + params[0] + postfix;
|
result = prefix + params[0] + postfix;
|
||||||
params.unshift(prefix + '%s' + postfix);
|
params.unshift(prefix + '%s' + postfix);
|
||||||
return result === $.PrivateBin.helper.sprintf.apply(this, params) &&
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
result === $.PrivateBin.helper.sprintf(params);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
@ -261,8 +212,7 @@ describe('helper', function () {
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
||||||
result = prefix + params[0] + postfix;
|
result = prefix + params[0] + postfix;
|
||||||
params.unshift(prefix + '%d' + postfix);
|
params.unshift(prefix + '%d' + postfix);
|
||||||
return result === $.PrivateBin.helper.sprintf.apply(this, params) &&
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
result === $.PrivateBin.helper.sprintf(params);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
@ -275,8 +225,7 @@ describe('helper', function () {
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
||||||
result = prefix + '0' + postfix;
|
result = prefix + '0' + postfix;
|
||||||
params.unshift(prefix + '%d' + postfix);
|
params.unshift(prefix + '%d' + postfix);
|
||||||
return result === $.PrivateBin.helper.sprintf.apply(this, params) &&
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params)
|
||||||
result === $.PrivateBin.helper.sprintf(params);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
@ -291,8 +240,7 @@ describe('helper', function () {
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
||||||
params = [prefix + '%d' + middle + '%s' + postfix, uint, string],
|
params = [prefix + '%d' + middle + '%s' + postfix, uint, string],
|
||||||
result = prefix + uint + middle + string + postfix;
|
result = prefix + uint + middle + string + postfix;
|
||||||
return result === $.PrivateBin.helper.sprintf.apply(this, params) &&
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
result === $.PrivateBin.helper.sprintf(params);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
|
@ -307,8 +255,7 @@ describe('helper', function () {
|
||||||
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
postfix = postfix.replace(/%(s|d)/g, '%%'),
|
||||||
params = [prefix + '%s' + middle + '%d' + postfix, string, uint],
|
params = [prefix + '%s' + middle + '%d' + postfix, string, uint],
|
||||||
result = prefix + string + middle + uint + postfix;
|
result = prefix + string + middle + uint + postfix;
|
||||||
return result === $.PrivateBin.helper.sprintf.apply(this, params) &&
|
return result === $.PrivateBin.Helper.sprintf.apply(this, params);
|
||||||
result === $.PrivateBin.helper.sprintf(params);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -333,88 +280,35 @@ describe('helper', function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var clean = jsdom('', {cookie: cookieArray}),
|
var clean = jsdom('', {cookie: cookieArray}),
|
||||||
result = $.PrivateBin.helper.getCookie(selectedKey);
|
result = $.PrivateBin.Helper.getCookie(selectedKey);
|
||||||
clean();
|
clean();
|
||||||
return result === selectedValue;
|
return result === selectedValue;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scriptLocation', function () {
|
describe('baseUri', function () {
|
||||||
|
before(function () {
|
||||||
|
$.PrivateBin.Helper.reset();
|
||||||
|
});
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the URL without query & fragment',
|
'returns the URL without query & fragment',
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
jsc.elements(schemas),
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
jsc.array(jsc.elements(queryString)),
|
jsc.array(jsc.elements(queryString)),
|
||||||
'string',
|
'string',
|
||||||
function (schema, address, query, fragment) {
|
function (schema, address, query, fragment) {
|
||||||
var expected = schema.join('') + '://' + address.join('') + '/',
|
var expected = schema + '://' + address.join('') + '/',
|
||||||
clean = jsdom('', {url: expected + '?' + query.join('') + '#' + fragment}),
|
clean = jsdom('', {url: expected + '?' + query.join('') + '#' + fragment}),
|
||||||
result = $.PrivateBin.helper.scriptLocation();
|
result = $.PrivateBin.Helper.baseUri();
|
||||||
|
$.PrivateBin.Helper.reset();
|
||||||
clean();
|
clean();
|
||||||
return expected === result;
|
return expected === result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('pasteId', function () {
|
|
||||||
jsc.property(
|
|
||||||
'returns the query string without separator, if any',
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.array(jsc.elements(queryString)),
|
|
||||||
'string',
|
|
||||||
function (schema, address, query, fragment) {
|
|
||||||
var queryString = query.join(''),
|
|
||||||
clean = jsdom('', {
|
|
||||||
url: schema.join('') + '://' + address.join('') +
|
|
||||||
'/?' + queryString + '#' + fragment
|
|
||||||
}),
|
|
||||||
result = $.PrivateBin.helper.pasteId();
|
|
||||||
clean();
|
|
||||||
return queryString === result;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('pageKey', function () {
|
|
||||||
jsc.property(
|
|
||||||
'returns the fragment of the URL',
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.array(jsc.elements(queryString)),
|
|
||||||
jsc.array(jsc.elements(base64String)),
|
|
||||||
function (schema, address, query, fragment) {
|
|
||||||
var fragmentString = fragment.join(''),
|
|
||||||
clean = jsdom('', {
|
|
||||||
url: schema.join('') + '://' + address.join('') +
|
|
||||||
'/?' + query.join('') + '#' + fragmentString
|
|
||||||
}),
|
|
||||||
result = $.PrivateBin.helper.pageKey();
|
|
||||||
clean();
|
|
||||||
return fragmentString === result;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
jsc.property(
|
|
||||||
'returns the fragment stripped of trailing query parts',
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.nearray(jsc.elements(a2zString)),
|
|
||||||
jsc.array(jsc.elements(queryString)),
|
|
||||||
jsc.array(jsc.elements(base64String)),
|
|
||||||
jsc.array(jsc.elements(queryString)),
|
|
||||||
function (schema, address, query, fragment, trail) {
|
|
||||||
var fragmentString = fragment.join(''),
|
|
||||||
clean = jsdom('', {
|
|
||||||
url: schema.join('') + '://' + address.join('') + '/?' +
|
|
||||||
query.join('') + '#' + fragmentString + '&' + trail.join('')
|
|
||||||
}),
|
|
||||||
result = $.PrivateBin.helper.pageKey();
|
|
||||||
clean();
|
|
||||||
return fragmentString === result;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('htmlEntities', function () {
|
describe('htmlEntities', function () {
|
||||||
after(function () {
|
after(function () {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
@ -424,9 +318,76 @@ describe('helper', function () {
|
||||||
'removes all HTML entities from any given string',
|
'removes all HTML entities from any given string',
|
||||||
'string',
|
'string',
|
||||||
function (string) {
|
function (string) {
|
||||||
var result = $.PrivateBin.helper.htmlEntities(string);
|
var result = $.PrivateBin.Helper.htmlEntities(string);
|
||||||
return !(/[<>"'`=\/]/.test(result)) && !(string.indexOf('&') > -1 && !(/&/.test(result)));
|
return !(/[<>"'`=\/]/.test(result)) && !(string.indexOf('&') > -1 && !(/&/.test(result)));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Model', function () {
|
||||||
|
describe('getPasteId', function () {
|
||||||
|
before(function () {
|
||||||
|
$.PrivateBin.Model.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'returns the query string without separator, if any',
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.nearray(jsc.elements(queryString)),
|
||||||
|
'string',
|
||||||
|
function (schema, address, query, fragment) {
|
||||||
|
var queryString = query.join(''),
|
||||||
|
clean = jsdom('', {
|
||||||
|
url: schema.join('') + '://' + address.join('') +
|
||||||
|
'/?' + queryString + '#' + fragment
|
||||||
|
}),
|
||||||
|
result = $.PrivateBin.Model.getPasteId();
|
||||||
|
$.PrivateBin.Model.reset();
|
||||||
|
clean();
|
||||||
|
return queryString === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getPasteKey', function () {
|
||||||
|
jsc.property(
|
||||||
|
'returns the fragment of the URL',
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.array(jsc.elements(queryString)),
|
||||||
|
jsc.nearray(jsc.elements(base64String)),
|
||||||
|
function (schema, address, query, fragment) {
|
||||||
|
var fragmentString = fragment.join(''),
|
||||||
|
clean = jsdom('', {
|
||||||
|
url: schema.join('') + '://' + address.join('') +
|
||||||
|
'/?' + query.join('') + '#' + fragmentString
|
||||||
|
}),
|
||||||
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
|
$.PrivateBin.Model.reset();
|
||||||
|
clean();
|
||||||
|
return fragmentString === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
jsc.property(
|
||||||
|
'returns the fragment stripped of trailing query parts',
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.nearray(jsc.elements(a2zString)),
|
||||||
|
jsc.array(jsc.elements(queryString)),
|
||||||
|
jsc.nearray(jsc.elements(base64String)),
|
||||||
|
jsc.array(jsc.elements(queryString)),
|
||||||
|
function (schema, address, query, fragment, trail) {
|
||||||
|
var fragmentString = fragment.join(''),
|
||||||
|
clean = jsdom('', {
|
||||||
|
url: schema.join('') + '://' + address.join('') + '/?' +
|
||||||
|
query.join('') + '#' + fragmentString + '&' + trail.join('')
|
||||||
|
}),
|
||||||
|
result = $.PrivateBin.Model.getPasteKey();
|
||||||
|
$.PrivateBin.Model.reset();
|
||||||
|
clean();
|
||||||
|
return fragmentString === result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
Allow from none
|
Require all denied
|
||||||
Deny from all
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ abstract class AbstractData
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return privatebin_abstract
|
* @return AbstractData
|
||||||
*/
|
*/
|
||||||
public static function getInstance($options)
|
public static function getInstance($options)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,6 @@ abstract class AbstractData
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $pasteid
|
* @param string $pasteid
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
abstract public function delete($pasteid);
|
abstract public function delete($pasteid);
|
||||||
|
|
||||||
|
@ -147,7 +146,6 @@ abstract class AbstractData
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param int $batchsize
|
* @param int $batchsize
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function purge($batchsize)
|
public function purge($batchsize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -282,7 +282,6 @@ class Database extends AbstractData
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $pasteid
|
* @param string $pasteid
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function delete($pasteid)
|
public function delete($pasteid)
|
||||||
{
|
{
|
||||||
|
@ -375,11 +374,10 @@ class Database extends AbstractData
|
||||||
$comments[$i]->data = $row['data'];
|
$comments[$i]->data = $row['data'];
|
||||||
$comments[$i]->meta = new stdClass;
|
$comments[$i]->meta = new stdClass;
|
||||||
$comments[$i]->meta->postdate = (int) $row['postdate'];
|
$comments[$i]->meta->postdate = (int) $row['postdate'];
|
||||||
if (array_key_exists('nickname', $row) && !empty($row['nickname'])) {
|
foreach (array('nickname', 'vizhash') as $key) {
|
||||||
$comments[$i]->meta->nickname = $row['nickname'];
|
if (array_key_exists($key, $row) && !empty($row[$key])) {
|
||||||
|
$comments[$i]->meta->$key = $row[$key];
|
||||||
}
|
}
|
||||||
if (array_key_exists('vizhash', $row) && !empty($row['vizhash'])) {
|
|
||||||
$comments[$i]->meta->vizhash = $row['vizhash'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ksort($comments);
|
ksort($comments);
|
||||||
|
@ -564,7 +562,6 @@ class Database extends AbstractData
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @static
|
* @static
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private static function _createPasteTable()
|
private static function _createPasteTable()
|
||||||
{
|
{
|
||||||
|
@ -589,7 +586,6 @@ class Database extends AbstractData
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @static
|
* @static
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private static function _createCommentTable()
|
private static function _createCommentTable()
|
||||||
{
|
{
|
||||||
|
@ -616,7 +612,6 @@ class Database extends AbstractData
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @static
|
* @static
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private static function _createConfigTable()
|
private static function _createConfigTable()
|
||||||
{
|
{
|
||||||
|
@ -651,7 +646,6 @@ class Database extends AbstractData
|
||||||
* @access private
|
* @access private
|
||||||
* @static
|
* @static
|
||||||
* @param string $oldversion
|
* @param string $oldversion
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private static function _upgradeDatabase($oldversion)
|
private static function _upgradeDatabase($oldversion)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
namespace PrivateBin\Data;
|
namespace PrivateBin\Data;
|
||||||
|
|
||||||
use PrivateBin\Json;
|
|
||||||
use PrivateBin\Model\Paste;
|
use PrivateBin\Model\Paste;
|
||||||
|
use PrivateBin\Persistence\DataStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filesystem
|
* Filesystem
|
||||||
|
@ -22,15 +22,6 @@ use PrivateBin\Model\Paste;
|
||||||
*/
|
*/
|
||||||
class Filesystem extends AbstractData
|
class Filesystem extends AbstractData
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* directory where data is stored
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @static
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private static $_dir = 'data/';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get instance of singleton
|
* get instance of singleton
|
||||||
*
|
*
|
||||||
|
@ -41,17 +32,16 @@ class Filesystem extends AbstractData
|
||||||
*/
|
*/
|
||||||
public static function getInstance($options = null)
|
public static function getInstance($options = null)
|
||||||
{
|
{
|
||||||
|
// if needed initialize the singleton
|
||||||
|
if (!(self::$_instance instanceof self)) {
|
||||||
|
self::$_instance = new self;
|
||||||
|
}
|
||||||
// if given update the data directory
|
// if given update the data directory
|
||||||
if (
|
if (
|
||||||
is_array($options) &&
|
is_array($options) &&
|
||||||
array_key_exists('dir', $options)
|
array_key_exists('dir', $options)
|
||||||
) {
|
) {
|
||||||
self::$_dir = $options['dir'] . DIRECTORY_SEPARATOR;
|
DataStore::setPath($options['dir']);
|
||||||
}
|
|
||||||
// if needed initialize the singleton
|
|
||||||
if (!(self::$_instance instanceof self)) {
|
|
||||||
self::$_instance = new self;
|
|
||||||
self::_init();
|
|
||||||
}
|
}
|
||||||
return self::$_instance;
|
return self::$_instance;
|
||||||
}
|
}
|
||||||
|
@ -62,19 +52,19 @@ class Filesystem extends AbstractData
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $pasteid
|
* @param string $pasteid
|
||||||
* @param array $paste
|
* @param array $paste
|
||||||
* @throws Exception
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function create($pasteid, $paste)
|
public function create($pasteid, $paste)
|
||||||
{
|
{
|
||||||
$storagedir = self::_dataid2path($pasteid);
|
$storagedir = self::_dataid2path($pasteid);
|
||||||
if (is_file($storagedir . $pasteid)) {
|
$file = $storagedir . $pasteid;
|
||||||
|
if (is_file($file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!is_dir($storagedir)) {
|
if (!is_dir($storagedir)) {
|
||||||
mkdir($storagedir, 0700, true);
|
mkdir($storagedir, 0700, true);
|
||||||
}
|
}
|
||||||
return (bool) file_put_contents($storagedir . $pasteid, Json::encode($paste));
|
return DataStore::store($file, $paste);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,7 +98,6 @@ class Filesystem extends AbstractData
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $pasteid
|
* @param string $pasteid
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function delete($pasteid)
|
public function delete($pasteid)
|
||||||
{
|
{
|
||||||
|
@ -155,20 +144,19 @@ class Filesystem extends AbstractData
|
||||||
* @param string $parentid
|
* @param string $parentid
|
||||||
* @param string $commentid
|
* @param string $commentid
|
||||||
* @param array $comment
|
* @param array $comment
|
||||||
* @throws Exception
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createComment($pasteid, $parentid, $commentid, $comment)
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
||||||
{
|
{
|
||||||
$storagedir = self::_dataid2discussionpath($pasteid);
|
$storagedir = self::_dataid2discussionpath($pasteid);
|
||||||
$filename = $pasteid . '.' . $commentid . '.' . $parentid;
|
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid;
|
||||||
if (is_file($storagedir . $filename)) {
|
if (is_file($file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!is_dir($storagedir)) {
|
if (!is_dir($storagedir)) {
|
||||||
mkdir($storagedir, 0700, true);
|
mkdir($storagedir, 0700, true);
|
||||||
}
|
}
|
||||||
return (bool) file_put_contents($storagedir . $filename, Json::encode($comment));
|
return DataStore::store($file, $comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,8 +225,9 @@ class Filesystem extends AbstractData
|
||||||
protected function _getExpiredPastes($batchsize)
|
protected function _getExpiredPastes($batchsize)
|
||||||
{
|
{
|
||||||
$pastes = array();
|
$pastes = array();
|
||||||
|
$mainpath = DataStore::getPath();
|
||||||
$firstLevel = array_filter(
|
$firstLevel = array_filter(
|
||||||
scandir(self::$_dir),
|
scandir($mainpath),
|
||||||
'self::_isFirstLevelDir'
|
'self::_isFirstLevelDir'
|
||||||
);
|
);
|
||||||
if (count($firstLevel) > 0) {
|
if (count($firstLevel) > 0) {
|
||||||
|
@ -246,7 +235,7 @@ class Filesystem extends AbstractData
|
||||||
for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
|
for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
|
||||||
$firstKey = array_rand($firstLevel);
|
$firstKey = array_rand($firstLevel);
|
||||||
$secondLevel = array_filter(
|
$secondLevel = array_filter(
|
||||||
scandir(self::$_dir . $firstLevel[$firstKey]),
|
scandir($mainpath . DIRECTORY_SEPARATOR . $firstLevel[$firstKey]),
|
||||||
'self::_isSecondLevelDir'
|
'self::_isSecondLevelDir'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -257,8 +246,9 @@ class Filesystem extends AbstractData
|
||||||
}
|
}
|
||||||
|
|
||||||
$secondKey = array_rand($secondLevel);
|
$secondKey = array_rand($secondLevel);
|
||||||
$path = self::$_dir . $firstLevel[$firstKey] .
|
$path = $mainpath . DIRECTORY_SEPARATOR .
|
||||||
DIRECTORY_SEPARATOR . $secondLevel[$secondKey];
|
$firstLevel[$firstKey] . DIRECTORY_SEPARATOR .
|
||||||
|
$secondLevel[$secondKey];
|
||||||
if (!is_dir($path)) {
|
if (!is_dir($path)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -292,29 +282,6 @@ class Filesystem extends AbstractData
|
||||||
return $pastes;
|
return $pastes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* initialize privatebin
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @static
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private static function _init()
|
|
||||||
{
|
|
||||||
// Create storage directory if it does not exist.
|
|
||||||
if (!is_dir(self::$_dir)) {
|
|
||||||
mkdir(self::$_dir, 0700);
|
|
||||||
}
|
|
||||||
// Create .htaccess file if it does not exist.
|
|
||||||
if (!is_file(self::$_dir . '.htaccess')) {
|
|
||||||
file_put_contents(
|
|
||||||
self::$_dir . '.htaccess',
|
|
||||||
'Allow from none' . PHP_EOL .
|
|
||||||
'Deny from all' . PHP_EOL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert paste id to storage path.
|
* Convert paste id to storage path.
|
||||||
*
|
*
|
||||||
|
@ -332,8 +299,10 @@ class Filesystem extends AbstractData
|
||||||
*/
|
*/
|
||||||
private static function _dataid2path($dataid)
|
private static function _dataid2path($dataid)
|
||||||
{
|
{
|
||||||
return self::$_dir . substr($dataid, 0, 2) . DIRECTORY_SEPARATOR .
|
return DataStore::getPath(
|
||||||
substr($dataid, 2, 2) . DIRECTORY_SEPARATOR;
|
substr($dataid, 0, 2) . DIRECTORY_SEPARATOR .
|
||||||
|
substr($dataid, 2, 2) . DIRECTORY_SEPARATOR
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -363,7 +332,7 @@ class Filesystem extends AbstractData
|
||||||
private static function _isFirstLevelDir($element)
|
private static function _isFirstLevelDir($element)
|
||||||
{
|
{
|
||||||
return self::_isSecondLevelDir($element) &&
|
return self::_isSecondLevelDir($element) &&
|
||||||
is_dir(self::$_dir . DIRECTORY_SEPARATOR . $element);
|
is_dir(DataStore::getPath($element));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,21 +21,6 @@ use Exception;
|
||||||
*/
|
*/
|
||||||
class Filter
|
class Filter
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* strips slashes deeply
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @static
|
|
||||||
* @param mixed $value
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public static function stripslashesDeep($value)
|
|
||||||
{
|
|
||||||
return is_array($value) ?
|
|
||||||
array_map('self::stripslashesDeep', $value) :
|
|
||||||
stripslashes($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* format a given time string into a human readable label (localized)
|
* format a given time string into a human readable label (localized)
|
||||||
*
|
*
|
||||||
|
|
11
lib/I18n.php
11
lib/I18n.php
|
@ -135,15 +135,17 @@ class I18n
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function loadTranslations()
|
public static function loadTranslations()
|
||||||
{
|
{
|
||||||
$availableLanguages = self::getAvailableLanguages();
|
$availableLanguages = self::getAvailableLanguages();
|
||||||
|
|
||||||
// check if the lang cookie was set and that language exists
|
// check if the lang cookie was set and that language exists
|
||||||
if (array_key_exists('lang', $_COOKIE) && in_array($_COOKIE['lang'], $availableLanguages)) {
|
if (
|
||||||
$match = $_COOKIE['lang'];
|
array_key_exists('lang', $_COOKIE) &&
|
||||||
|
($key = array_search($_COOKIE['lang'], $availableLanguages)) !== false
|
||||||
|
) {
|
||||||
|
$match = $availableLanguages[$key];
|
||||||
}
|
}
|
||||||
// find a translation file matching the browsers language preferences
|
// find a translation file matching the browsers language preferences
|
||||||
else {
|
else {
|
||||||
|
@ -256,7 +258,6 @@ class I18n
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param string $lang
|
* @param string $lang
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setLanguageFallback($lang)
|
public static function setLanguageFallback($lang)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +305,7 @@ class I18n
|
||||||
return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
|
return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
|
||||||
case 'sl':
|
case 'sl':
|
||||||
return $n % 100 == 1 ? 1 : ($n % 100 == 2 ? 2 : ($n % 100 == 3 || $n % 100 == 4 ? 3 : 0));
|
return $n % 100 == 1 ? 1 : ($n % 100 == 2 ? 2 : ($n % 100 == 3 || $n % 100 == 4 ? 3 : 0));
|
||||||
// de, en, es, it, no
|
// de, en, es, it, no, pt
|
||||||
default:
|
default:
|
||||||
return $n != 1 ? 1 : 0;
|
return $n != 1 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ class Model
|
||||||
* Factory constructor.
|
* Factory constructor.
|
||||||
*
|
*
|
||||||
* @param configuration $conf
|
* @param configuration $conf
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function __construct(Configuration $conf)
|
public function __construct(Configuration $conf)
|
||||||
{
|
{
|
||||||
|
@ -64,8 +63,6 @@ class Model
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a purge is necessary and triggers it if yes.
|
* Checks if a purge is necessary and triggers it if yes.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function purge()
|
public function purge()
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,6 @@ abstract class AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param Configuration $configuration
|
* @param Configuration $configuration
|
||||||
* @param AbstractData $storage
|
* @param AbstractData $storage
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function __construct(Configuration $configuration, AbstractData $storage)
|
public function __construct(Configuration $configuration, AbstractData $storage)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +89,6 @@ abstract class AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setId($id)
|
public function setId($id)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +104,6 @@ abstract class AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $data
|
* @param string $data
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setData($data)
|
public function setData($data)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +130,6 @@ abstract class AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
abstract public function store();
|
abstract public function store();
|
||||||
|
|
||||||
|
@ -142,7 +138,6 @@ abstract class AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
abstract public function delete();
|
abstract public function delete();
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ class Comment extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
|
@ -101,7 +100,6 @@ class Comment extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
|
@ -129,7 +127,6 @@ class Comment extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param Paste $paste
|
* @param Paste $paste
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setPaste(Paste $paste)
|
public function setPaste(Paste $paste)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +151,6 @@ class Comment extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setParentId($id)
|
public function setParentId($id)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +180,6 @@ class Comment extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $nickname
|
* @param string $nickname
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setNickname($nickname)
|
public function setNickname($nickname)
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,7 +75,6 @@ class Paste extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
|
@ -103,7 +102,6 @@ class Paste extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
|
@ -183,7 +181,6 @@ class Paste extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $attachment
|
* @param string $attachment
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setAttachment($attachment)
|
public function setAttachment($attachment)
|
||||||
{
|
{
|
||||||
|
@ -199,7 +196,6 @@ class Paste extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $attachmentname
|
* @param string $attachmentname
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setAttachmentName($attachmentname)
|
public function setAttachmentName($attachmentname)
|
||||||
{
|
{
|
||||||
|
@ -214,7 +210,6 @@ class Paste extends AbstractModel
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $expiration
|
* @param string $expiration
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setExpiration($expiration)
|
public function setExpiration($expiration)
|
||||||
{
|
{
|
||||||
|
@ -236,7 +231,6 @@ class Paste extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $burnafterreading
|
* @param string $burnafterreading
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setBurnafterreading($burnafterreading = '1')
|
public function setBurnafterreading($burnafterreading = '1')
|
||||||
{
|
{
|
||||||
|
@ -257,7 +251,6 @@ class Paste extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $opendiscussion
|
* @param string $opendiscussion
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setOpendiscussion($opendiscussion = '1')
|
public function setOpendiscussion($opendiscussion = '1')
|
||||||
{
|
{
|
||||||
|
@ -281,7 +274,6 @@ class Paste extends AbstractModel
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $format
|
* @param string $format
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setFormatter($format)
|
public function setFormatter($format)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,6 @@ abstract class AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setPath($path)
|
public static function setPath($path)
|
||||||
{
|
{
|
||||||
|
@ -80,27 +79,23 @@ abstract class AbstractPersistence
|
||||||
* @access protected
|
* @access protected
|
||||||
* @static
|
* @static
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
protected static function _initialize()
|
protected static function _initialize()
|
||||||
{
|
{
|
||||||
// Create storage directory if it does not exist.
|
// Create storage directory if it does not exist.
|
||||||
if (!is_dir(self::$_path)) {
|
if (!is_dir(self::$_path)) {
|
||||||
if (!@mkdir(self::$_path)) {
|
if (!@mkdir(self::$_path, 0700)) {
|
||||||
throw new Exception('unable to create directory ' . self::$_path, 10);
|
throw new Exception('unable to create directory ' . self::$_path, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create .htaccess file if it does not exist.
|
|
||||||
$file = self::$_path . DIRECTORY_SEPARATOR . '.htaccess';
|
$file = self::$_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||||
if (!is_file($file)) {
|
if (!is_file($file)) {
|
||||||
$writtenBytes = @file_put_contents(
|
$writtenBytes = @file_put_contents(
|
||||||
$file,
|
$file,
|
||||||
'Allow from none' . PHP_EOL .
|
'Require all denied' . PHP_EOL,
|
||||||
'Deny from all' . PHP_EOL,
|
|
||||||
LOCK_EX
|
LOCK_EX
|
||||||
);
|
);
|
||||||
if ($writtenBytes === false || $writtenBytes < 30) {
|
if ($writtenBytes === false || $writtenBytes < 19) {
|
||||||
throw new Exception('unable to write to file ' . $file, 11);
|
throw new Exception('unable to write to file ' . $file, 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
lib/Persistence/DataStore.php
Normal file
47
lib/Persistence/DataStore.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PrivateBin
|
||||||
|
*
|
||||||
|
* a zero-knowledge paste bin
|
||||||
|
*
|
||||||
|
* @link https://github.com/PrivateBin/PrivateBin
|
||||||
|
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||||
|
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||||
|
* @version 1.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PrivateBin\Persistence;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use PrivateBin\Json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataStore
|
||||||
|
*
|
||||||
|
* Handles data storage for Data\Filesystem.
|
||||||
|
*/
|
||||||
|
class DataStore extends AbstractPersistence
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* store the data
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param string $filename
|
||||||
|
* @param array $data
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function store($filename, $data)
|
||||||
|
{
|
||||||
|
$path = self::getPath();
|
||||||
|
if (strpos($filename, $path) === 0) {
|
||||||
|
$filename = substr($filename, strlen($path));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
self::_store($filename, Json::encode($data));
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,7 +36,6 @@ class PurgeLimiter extends AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setLimit($limit)
|
public static function setLimit($limit)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +48,6 @@ class PurgeLimiter extends AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param Configuration $conf
|
* @param Configuration $conf
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setConfiguration(Configuration $conf)
|
public static function setConfiguration(Configuration $conf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,7 +95,6 @@ class ServerSalt extends AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setPath($path)
|
public static function setPath($path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,7 +45,6 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setLimit($limit)
|
public static function setLimit($limit)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +57,6 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
* @param Configuration $conf
|
* @param Configuration $conf
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public static function setConfiguration(Configuration $conf)
|
public static function setConfiguration(Configuration $conf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,13 @@ class PrivateBin
|
||||||
*/
|
*/
|
||||||
const VERSION = '1.1';
|
const VERSION = '1.1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* minimal required PHP version
|
||||||
|
*
|
||||||
|
* @const string
|
||||||
|
*/
|
||||||
|
const MIN_PHP_VERSION = '5.4.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the same error message if the paste expired or does not exist
|
* show the same error message if the paste expired or does not exist
|
||||||
*
|
*
|
||||||
|
@ -116,12 +123,11 @@ class PrivateBin
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (version_compare(PHP_VERSION, '5.3.0') < 0) {
|
if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
|
||||||
throw new Exception(I18n::_('%s requires php 5.3.0 or above to work. Sorry.', I18n::_('PrivateBin')), 1);
|
throw new Exception(I18n::_('%s requires php %s or above to work. Sorry.', I18n::_('PrivateBin'), self::MIN_PHP_VERSION), 1);
|
||||||
}
|
}
|
||||||
if (strlen(PATH) < 0 && substr(PATH, -1) !== DIRECTORY_SEPARATOR) {
|
if (strlen(PATH) < 0 && substr(PATH, -1) !== DIRECTORY_SEPARATOR) {
|
||||||
throw new Exception(I18n::_('%s requires the PATH to end in a "%s". Please update the PATH in your index.php.', I18n::_('PrivateBin'), DIRECTORY_SEPARATOR), 5);
|
throw new Exception(I18n::_('%s requires the PATH to end in a "%s". Please update the PATH in your index.php.', I18n::_('PrivateBin'), DIRECTORY_SEPARATOR), 5);
|
||||||
|
@ -164,21 +170,9 @@ class PrivateBin
|
||||||
* initialize privatebin
|
* initialize privatebin
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _init()
|
private function _init()
|
||||||
{
|
{
|
||||||
foreach (array('cfg', 'lib') as $dir) {
|
|
||||||
if (!is_file(PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess')) {
|
|
||||||
file_put_contents(
|
|
||||||
PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess',
|
|
||||||
'Allow from none' . PHP_EOL .
|
|
||||||
'Deny from all' . PHP_EOL,
|
|
||||||
LOCK_EX
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_conf = new Configuration;
|
$this->_conf = new Configuration;
|
||||||
$this->_model = new Model($this->_conf);
|
$this->_model = new Model($this->_conf);
|
||||||
$this->_request = new Request;
|
$this->_request = new Request;
|
||||||
|
@ -324,7 +318,6 @@ class PrivateBin
|
||||||
* @access private
|
* @access private
|
||||||
* @param string $dataid
|
* @param string $dataid
|
||||||
* @param string $deletetoken
|
* @param string $deletetoken
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _delete($dataid, $deletetoken)
|
private function _delete($dataid, $deletetoken)
|
||||||
{
|
{
|
||||||
|
@ -334,19 +327,16 @@ class PrivateBin
|
||||||
// accessing this property ensures that the paste would be
|
// accessing this property ensures that the paste would be
|
||||||
// deleted if it has already expired
|
// deleted if it has already expired
|
||||||
$burnafterreading = $paste->isBurnafterreading();
|
$burnafterreading = $paste->isBurnafterreading();
|
||||||
if ($deletetoken == 'burnafterreading') {
|
if (
|
||||||
if ($burnafterreading) {
|
($burnafterreading && $deletetoken == 'burnafterreading') ||
|
||||||
$paste->delete();
|
Filter::slowEquals($deletetoken, $paste->getDeleteToken())
|
||||||
$this->_return_message(0, $dataid);
|
) {
|
||||||
} else {
|
|
||||||
$this->_return_message(1, 'Paste is not of burn-after-reading type.');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Make sure the token is valid.
|
|
||||||
if (Filter::slowEquals($deletetoken, $paste->getDeleteToken())) {
|
|
||||||
// Paste exists and deletion token is valid: Delete the paste.
|
// Paste exists and deletion token is valid: Delete the paste.
|
||||||
$paste->delete();
|
$paste->delete();
|
||||||
$this->_status = 'Paste was properly deleted.';
|
$this->_status = 'Paste was properly deleted.';
|
||||||
|
} else {
|
||||||
|
if (!$burnafterreading && $deletetoken == 'burnafterreading') {
|
||||||
|
$this->_error = 'Paste is not of burn-after-reading type.';
|
||||||
} else {
|
} else {
|
||||||
$this->_error = 'Wrong deletion token. Paste was not deleted.';
|
$this->_error = 'Wrong deletion token. Paste was not deleted.';
|
||||||
}
|
}
|
||||||
|
@ -357,6 +347,13 @@ class PrivateBin
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->_error = $e->getMessage();
|
$this->_error = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
if ($this->_request->isJsonApiCall()) {
|
||||||
|
if (strlen($this->_error)) {
|
||||||
|
$this->_return_message(1, $this->_error);
|
||||||
|
} else {
|
||||||
|
$this->_return_message(0, $dataid);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -364,7 +361,6 @@ class PrivateBin
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param string $dataid
|
* @param string $dataid
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _read($dataid)
|
private function _read($dataid)
|
||||||
{
|
{
|
||||||
|
@ -397,7 +393,6 @@ class PrivateBin
|
||||||
* Display PrivateBin frontend.
|
* Display PrivateBin frontend.
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _view()
|
private function _view()
|
||||||
{
|
{
|
||||||
|
@ -461,7 +456,6 @@ class PrivateBin
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _jsonld($type)
|
private function _jsonld($type)
|
||||||
{
|
{
|
||||||
|
@ -494,7 +488,6 @@ class PrivateBin
|
||||||
* @param int $status
|
* @param int $status
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @param array $other
|
* @param array $other
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function _return_message($status, $message, $other = array())
|
private function _return_message($status, $message, $other = array())
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Request
|
||||||
const MIME_XHTML = 'application/xhtml+xml';
|
const MIME_XHTML = 'application/xhtml+xml';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input stream to use for PUT parameter parsing.
|
* Input stream to use for PUT parameter parsing
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -49,7 +49,7 @@ class Request
|
||||||
private static $_inputStream = 'php://input';
|
private static $_inputStream = 'php://input';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operation to perform.
|
* Operation to perform
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -57,7 +57,7 @@ class Request
|
||||||
private $_operation = 'view';
|
private $_operation = 'view';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request parameters.
|
* Request parameters
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var array
|
* @var array
|
||||||
|
@ -65,7 +65,7 @@ class Request
|
||||||
private $_params = array();
|
private $_params = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we are in a JSON API context.
|
* If we are in a JSON API context
|
||||||
*
|
*
|
||||||
* @access private
|
* @access private
|
||||||
* @var bool
|
* @var bool
|
||||||
|
@ -73,20 +73,12 @@ class Request
|
||||||
private $_isJsonApi = false;
|
private $_isJsonApi = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
// in case stupid admin has left magic_quotes enabled in php.ini (for PHP < 5.4)
|
|
||||||
if (version_compare(PHP_VERSION, '5.4.0') < 0 && get_magic_quotes_gpc()) {
|
|
||||||
$_POST = array_map('PrivateBin\\Filter::stripslashesDeep', $_POST);
|
|
||||||
$_GET = array_map('PrivateBin\\Filter::stripslashesDeep', $_GET);
|
|
||||||
$_COOKIE = array_map('PrivateBin\\Filter::stripslashesDeep', $_COOKIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// decide if we are in JSON API or HTML context
|
// decide if we are in JSON API or HTML context
|
||||||
$this->_isJsonApi = $this->_detectJsonRequest();
|
$this->_isJsonApi = $this->_detectJsonRequest();
|
||||||
|
|
||||||
|
@ -129,7 +121,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current operation.
|
* Get current operation
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -140,7 +132,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a request parameter.
|
* Get a request parameter
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $param
|
* @param string $param
|
||||||
|
@ -153,7 +145,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we are in a JSON API context.
|
* If we are in a JSON API context
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return bool
|
* @return bool
|
||||||
|
@ -164,7 +156,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the default input stream source, used for unit testing.
|
* Override the default input stream source, used for unit testing
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
*/
|
*/
|
||||||
|
@ -174,7 +166,7 @@ class Request
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* detect the clients supported media type and decide if its a JSON API call or not
|
* Detect the clients supported media type and decide if its a JSON API call or not
|
||||||
*
|
*
|
||||||
* Adapted from: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
* Adapted from: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,7 +35,6 @@ class View
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function assign($name, $value)
|
public function assign($name, $value)
|
||||||
{
|
{
|
||||||
|
@ -48,7 +47,6 @@ class View
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $template
|
* @param string $template
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function draw($template)
|
public function draw($template)
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,6 @@ class Vizhash16x16
|
||||||
* constructor
|
* constructor
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
@ -210,7 +209,6 @@ class Vizhash16x16
|
||||||
* @param resource $image
|
* @param resource $image
|
||||||
* @param int $action
|
* @param int $action
|
||||||
* @param int $color
|
* @param int $color
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
private function drawshape($image, $action, $color)
|
private function drawshape($image, $action, $color)
|
||||||
{
|
{
|
||||||
|
|
1
tpl/.htaccess
Normal file
1
tpl/.htaccess
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Require all denied
|
|
@ -4,7 +4,7 @@ $isCpct = substr($template, 9, 8) === '-compact';
|
||||||
$isDark = substr($template, 9, 5) === '-dark';
|
$isDark = substr($template, 9, 5) === '-dark';
|
||||||
$isPage = substr($template, -5) === '-page';
|
$isPage = substr($template, -5) === '-page';
|
||||||
?><!DOCTYPE html>
|
?><!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
@ -69,7 +69,7 @@ if ($MARKDOWN):
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-Ap3kgrXsOa+7xANzug/xGKb3rEOzCYuJoxUG5vmwYRWn/8wI9Cc/RYZehKnFwHuFCFnQzfqJ9GT2D1HSOdnd5g==" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-xfoNRo43UxDcd7m1P2IsvSPcOeGJo1oUjbA+CNCBoBilKRU3Iuqbf7awv3knP50bX7PVGEjtS6yJ2KtOtqnhTA==" crossorigin="anonymous"></script>
|
||||||
<!--[if lt IE 10]>
|
<!--[if lt IE 10]>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
@ -94,7 +94,7 @@ endif;
|
||||||
<form id="passwordform" role="form">
|
<form id="passwordform" role="form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="passworddecrypt"><span class="glyphicon glyphicon-eye-open"></span> <?php echo I18n::_('Please enter the password for this paste:') ?></label>
|
<label for="passworddecrypt"><span class="glyphicon glyphicon-eye-open"></span> <?php echo I18n::_('Please enter the password for this paste:') ?></label>
|
||||||
<input id="passworddecrypt" type="password" class="form-control" placeholder="<?php echo I18n::_('Enter password') ?>" autofocus>
|
<input id="passworddecrypt" type="password" class="form-control" placeholder="<?php echo I18n::_('Enter password') ?>">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-success btn-block"><span class="glyphicon glyphicon-off"></span> <?php echo I18n::_('Decrypt') ?></button>
|
<button type="submit" class="btn btn-success btn-block"><span class="glyphicon glyphicon-off"></span> <?php echo I18n::_('Decrypt') ?></button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -121,8 +121,8 @@ endif;
|
||||||
<div id="navbar" class="navbar-collapse collapse">
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li id="loadingindicator" class="navbar-text hidden">
|
<li id="loadingindicator" class="navbar-text hidden">
|
||||||
<span class="glyphicon glyphicon-upload" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-time" aria-hidden="true"></span>
|
||||||
<?php echo I18n::_('Uploading paste… Please wait.'), PHP_EOL; ?>
|
<?php echo I18n::_('Loading…'), PHP_EOL; ?>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<?php
|
<?php
|
||||||
|
@ -132,7 +132,7 @@ if ($isPage):
|
||||||
<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo I18n::_('Send'), PHP_EOL;
|
<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?php echo I18n::_('Send'), PHP_EOL;
|
||||||
else:
|
else:
|
||||||
?>
|
?>
|
||||||
<button id="newbutton" type="button" class="reloadlink hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
|
<button id="newbutton" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
|
||||||
<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo I18n::_('New'), PHP_EOL;
|
<span class="glyphicon glyphicon-file" aria-hidden="true"></span> <?php echo I18n::_('New'), PHP_EOL;
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
|
@ -198,7 +198,7 @@ if ($isCpct):
|
||||||
<?php
|
<?php
|
||||||
if ($DISCUSSION):
|
if ($DISCUSSION):
|
||||||
?>
|
?>
|
||||||
<li id="opendisc" class="checkbox hidden">
|
<li id="opendiscussionoption" class="checkbox hidden">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
||||||
if ($OPENDISCUSSION):
|
if ($OPENDISCUSSION):
|
||||||
|
@ -230,17 +230,6 @@ if ($isCpct):
|
||||||
?>
|
?>
|
||||||
</ul>
|
</ul>
|
||||||
<select id="pasteFormatter" name="pasteFormatter" class="hidden">
|
<select id="pasteFormatter" name="pasteFormatter" class="hidden">
|
||||||
<?php
|
|
||||||
foreach ($FORMATTER as $key => $value):
|
|
||||||
?>
|
|
||||||
<option value="<?php echo $key; ?>"<?php
|
|
||||||
if ($key == $FORMATTERDEFAULT):
|
|
||||||
?> selected="selected"<?php
|
|
||||||
endif;
|
|
||||||
?>><?php echo $value; ?></option>
|
|
||||||
<?php
|
|
||||||
endforeach;
|
|
||||||
?>
|
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
<?php
|
<?php
|
||||||
|
@ -262,7 +251,7 @@ else:
|
||||||
if ($DISCUSSION):
|
if ($DISCUSSION):
|
||||||
?>
|
?>
|
||||||
<li>
|
<li>
|
||||||
<div id="opendisc" class="navbar-text checkbox hidden">
|
<div id="opendiscussionoption" class="navbar-text checkbox hidden">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
||||||
if ($OPENDISCUSSION):
|
if ($OPENDISCUSSION):
|
||||||
|
@ -295,6 +284,7 @@ if ($FILEUPLOAD):
|
||||||
<input type="file" id="file" name="file" />
|
<input type="file" id="file" name="file" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="customattachment" class="hidden"></li>
|
||||||
<li>
|
<li>
|
||||||
<a id="fileremovebutton" href="#">
|
<a id="fileremovebutton" href="#">
|
||||||
<?php echo I18n::_('Remove attachment'), PHP_EOL; ?>
|
<?php echo I18n::_('Remove attachment'), PHP_EOL; ?>
|
||||||
|
@ -383,49 +373,57 @@ if ($isCpct):
|
||||||
?></div><?php
|
?></div><?php
|
||||||
endif;
|
endif;
|
||||||
?></nav>
|
?></nav>
|
||||||
<header class="container">
|
<main>
|
||||||
|
<section class="container">
|
||||||
<?php
|
<?php
|
||||||
if (strlen($NOTICE)):
|
if (strlen($NOTICE)):
|
||||||
?>
|
?>
|
||||||
<div role="alert" class="alert alert-info">
|
<div role="alert" class="alert alert-info">
|
||||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <?php echo htmlspecialchars($NOTICE), PHP_EOL; ?>
|
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
||||||
|
<?php echo htmlspecialchars($NOTICE), PHP_EOL; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<div id="remainingtime" role="alert" class="hidden alert alert-info">
|
<div id="remainingtime" role="alert" class="hidden alert alert-info">
|
||||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-fire" aria-hidden="true"></span>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
if ($FILEUPLOAD):
|
if ($FILEUPLOAD):
|
||||||
?>
|
?>
|
||||||
<div id="attachment" role="alert" class="hidden alert alert-info">
|
<div id="attachment" role="alert" class="hidden alert alert-info">
|
||||||
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <a><?php echo I18n::_('Download attachment'); ?></a> <span id="clonedfile" class="hidden"><?php echo I18n::_('Cloned file attached.'); ?></span>
|
<span class="glyphicon glyphicon-download-alt" aria-hidden="true"></span>
|
||||||
</div>
|
<a class="alert-link"><?php echo I18n::_('Download attachment'), PHP_EOL; ?></a>
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
if (strlen($STATUS)):
|
|
||||||
?>
|
|
||||||
<div id="status" role="alert" class="alert alert-success">
|
|
||||||
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span> <?php echo htmlspecialchars($STATUS), PHP_EOL; ?>
|
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<div id="errormessage" role="alert" class="<?php
|
<div id="status" role="alert" class="statusmessage alert alert-info<?php echo empty($STATUS) ? ' hidden' : '' ?>">
|
||||||
if (!strlen($ERROR)):
|
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
|
||||||
?>hidden <?php
|
<?php echo htmlspecialchars($STATUS), PHP_EOL; ?>
|
||||||
endif;
|
</div>
|
||||||
?>alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo htmlspecialchars($ERROR); ?></div>
|
<div id="errormessage" role="alert" class="statusmessage<?php echo empty($ERROR) ? ' hidden' : '' ?> alert alert-danger">
|
||||||
<noscript><div id="noscript" role="alert" class="nonworking alert alert-<?php echo $isDark ? 'error' : 'warning'; ?>"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <?php echo I18n::_('JavaScript is required for %s to work.<br />Sorry for the inconvenience.', I18n::_($NAME)); ?></div></noscript>
|
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
||||||
<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger"><span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)); ?></div>
|
<?php echo htmlspecialchars($ERROR), PHP_EOL; ?>
|
||||||
<div id="ienotice" role="alert" class="hidden alert alert-<?php echo $isDark ? 'error' : 'warning'; ?>"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> <?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
</div>
|
||||||
|
<noscript>
|
||||||
|
<div id="noscript" role="alert" class="nonworking alert alert-<?php echo $isDark ? 'error' : 'warning'; ?>">
|
||||||
|
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||||
|
<?php echo I18n::_('JavaScript is required for %s to work.<br />Sorry for the inconvenience.', I18n::_($NAME)), PHP_EOL; ?>
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
<div id="oldienotice" role="alert" class="hidden nonworking alert alert-danger">
|
||||||
|
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
||||||
|
<?php echo I18n::_('%s requires a modern browser to work.', I18n::_($NAME)), PHP_EOL; ?>
|
||||||
|
</div>
|
||||||
|
<div id="ienotice" role="alert" class="hidden alert alert-<?php echo $isDark ? 'error' : 'warning'; ?>">
|
||||||
|
<span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
|
||||||
|
<?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
||||||
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
||||||
<a href="https://www.opera.com/">Opera</a>,
|
<a href="https://www.opera.com/">Opera</a>,
|
||||||
<a href="https://www.google.com/chrome">Chrome</a>,
|
<a href="https://www.google.com/chrome">Chrome</a>…
|
||||||
<a href="https://www.apple.com/safari">Safari</a>...
|
|
||||||
</div>
|
</div>
|
||||||
<div id="pasteresult" role="alert" class="hidden alert alert-success">
|
<div id="pasteSuccess" role="alert" class="hidden alert alert-success">
|
||||||
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||||
<div id="deletelink"></div>
|
<div id="deletelink"></div>
|
||||||
<div id="pastelink">
|
<div id="pastelink">
|
||||||
|
@ -440,30 +438,32 @@ endif;
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul id="preview" class="nav nav-tabs hidden">
|
<ul id="editorTabs" class="nav nav-tabs hidden">
|
||||||
<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo I18n::_('Editor'); ?></a></li>
|
<li role="presentation" class="active"><a id="messageedit" href="#"><?php echo I18n::_('Editor'); ?></a></li>
|
||||||
<li role="presentation"><a id="messagepreview" href="#"><?php echo I18n::_('Preview'); ?></a></li>
|
<li role="presentation"><a id="messagepreview" href="#"><?php echo I18n::_('Preview'); ?></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</header>
|
</section>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<article class="row">
|
<article class="row">
|
||||||
<div id="image" class="col-md-12 text-center hidden"></div>
|
<div id="placeholder" class="col-md-12 hidden"><?php echo I18n::_('+++ no paste text +++'); ?></div>
|
||||||
|
<div id="attachmentPreview" class="col-md-12 text-center hidden"></div>
|
||||||
<div id="prettymessage" class="col-md-12 hidden">
|
<div id="prettymessage" class="col-md-12 hidden">
|
||||||
<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
|
<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
|
||||||
</div>
|
</div>
|
||||||
<div id="cleartext" class="col-md-12 hidden"></div>
|
<div id="plaintext" class="col-md-12 hidden"></div>
|
||||||
<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
|
<p class="col-md-12"><textarea id="message" name="message" cols="80" rows="25" class="form-control hidden"></textarea></p>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<div id="discussion" class="hidden">
|
<div id="discussion" class="hidden">
|
||||||
<h4><?php echo I18n::_('Discussion'); ?></h4>
|
<h4><?php echo I18n::_('Discussion'); ?></h4>
|
||||||
<div id="comments"></div>
|
<div id="commentcontainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true">
|
<div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide">
|
||||||
<span> <?php echo I18n::_('Loading…'); ?></span><br>
|
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||||
|
<?php echo I18n::_('Loading…'); ?><br />
|
||||||
<span class="small"><?php echo I18n::_('In case this message never disappears please have a look at <a href="https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away">this FAQ for information to troubleshoot</a>.'); ?></span>
|
<span class="small"><?php echo I18n::_('In case this message never disappears please have a look at <a href="https://github.com/PrivateBin/PrivateBin/wiki/FAQ#why-does-not-the-loading-message-go-away">this FAQ for information to troubleshoot</a>.'); ?></span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -476,6 +476,21 @@ endif;
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
|
</main>
|
||||||
|
<div id="serverdata" class="hidden" aria-hidden="true">
|
||||||
|
<div id="cipherdata"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
|
||||||
|
<?php
|
||||||
|
if ($DISCUSSION):
|
||||||
|
?>
|
||||||
|
<div id="templates">
|
||||||
|
<!-- @TODO: when I intend/structure this corrrectly Firefox adds whitespaces everywhere which completly destroy the layout. (same possible when you remove the template data below and show this area in the browser) -->
|
||||||
|
<article id="commenttemplate" class="comment"><div class="commentmeta"><span class="nickname">name</span><span class="commentdate">0000-00-00</span></div><div class="commentdata">c</div><button class="btn btn-default btn-sm"><?php echo I18n::_('Reply'); ?></button></article>
|
||||||
|
<p id="commenttailtemplate" class="comment"><button class="btn btn-default btn-sm"><?php echo I18n::_('Add comment'); ?></button></p>
|
||||||
|
<div id="replytemplate" class="reply hidden"><input type="text" id="nickname" class="form-control" title="<?php echo I18n::_('Optional nickname…'); ?>" placeholder="<?php echo I18n::_('Optional nickname…'); ?>" /><textarea id="replymessage" class="replymessage form-control" cols="80" rows="7"></textarea><br /><div id="replystatus" role="alert" class="statusmessage hidden alert"><span class="glyphicon" aria-hidden="true"></span> </div><button id="replybutton" class="btn btn-default btn-sm"><?php echo I18n::_('Post comment'); ?></button></div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
26
tpl/page.php
26
tpl/page.php
|
@ -47,7 +47,7 @@ if ($MARKDOWN):
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-Ap3kgrXsOa+7xANzug/xGKb3rEOzCYuJoxUG5vmwYRWn/8wI9Cc/RYZehKnFwHuFCFnQzfqJ9GT2D1HSOdnd5g==" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-xfoNRo43UxDcd7m1P2IsvSPcOeGJo1oUjbA+CNCBoBilKRU3Iuqbf7awv3knP50bX7PVGEjtS6yJ2KtOtqnhTA==" crossorigin="anonymous"></script>
|
||||||
<!--[if lt IE 10]>
|
<!--[if lt IE 10]>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
@ -79,12 +79,12 @@ endif;
|
||||||
<div id="ienotice"><?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
<div id="ienotice"><?php echo I18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:'), PHP_EOL; ?>
|
||||||
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
<a href="https://www.mozilla.org/firefox/">Firefox</a>,
|
||||||
<a href="https://www.opera.com/">Opera</a>,
|
<a href="https://www.opera.com/">Opera</a>,
|
||||||
<a href="https://www.google.com/chrome">Chrome</a>,
|
<a href="https://www.google.com/chrome">Chrome</a>…
|
||||||
<a href="https://www.apple.com/safari">Safari</a>...
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<section>
|
<section>
|
||||||
<article>
|
<article>
|
||||||
|
<div id="loadingindicator" class="hidden"><?php echo I18n::_('Loading…'); ?></div>
|
||||||
<div id="status"><?php echo htmlspecialchars($STATUS); ?></div>
|
<div id="status"><?php echo htmlspecialchars($STATUS); ?></div>
|
||||||
<div id="errormessage" class="hidden"><?php echo htmlspecialchars($ERROR); ?></div>
|
<div id="errormessage" class="hidden"><?php echo htmlspecialchars($ERROR); ?></div>
|
||||||
<div id="toolbar">
|
<div id="toolbar">
|
||||||
|
@ -125,7 +125,7 @@ endif;
|
||||||
<?php
|
<?php
|
||||||
if ($DISCUSSION):
|
if ($DISCUSSION):
|
||||||
?>
|
?>
|
||||||
<div id="opendisc" class="button hidden">
|
<div id="opendiscussionoption" class="button hidden">
|
||||||
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
<input type="checkbox" id="opendiscussion" name="opendiscussion"<?php
|
||||||
if ($OPENDISCUSSION):
|
if ($OPENDISCUSSION):
|
||||||
?> checked="checked"<?php
|
?> checked="checked"<?php
|
||||||
|
@ -216,17 +216,31 @@ endif;
|
||||||
<div id="prettymessage" class="hidden">
|
<div id="prettymessage" class="hidden">
|
||||||
<pre id="prettyprint" class="prettyprint linenums:1"></pre>
|
<pre id="prettyprint" class="prettyprint linenums:1"></pre>
|
||||||
</div>
|
</div>
|
||||||
<div id="cleartext" class="hidden"></div>
|
<div id="plaintext" class="hidden"></div>
|
||||||
<textarea id="message" name="message" cols="80" rows="25" class="hidden"></textarea>
|
<textarea id="message" name="message" cols="80" rows="25" class="hidden"></textarea>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<div id="discussion" class="hidden">
|
<div id="discussion" class="hidden">
|
||||||
<h4 class="title"><?php echo I18n::_('Discussion'); ?></h4>
|
<h4 class="title"><?php echo I18n::_('Discussion'); ?></h4>
|
||||||
<div id="comments"></div>
|
<div id="commentcontainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<div id="serverdata" class="hidden" aria-hidden="true">
|
||||||
<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
|
<div id="cipherdata" class="hidden"><?php echo htmlspecialchars($CIPHERDATA, ENT_NOQUOTES); ?></div>
|
||||||
|
<?php
|
||||||
|
if ($DISCUSSION):
|
||||||
|
?>
|
||||||
|
<div id="templates">
|
||||||
|
<!-- @TODO: when I intend/structure this corrrectly Firefox adds whitespaces everywhere which completly destroy the layout. (same possible when you remove the template data below and show this area in the browser) -->
|
||||||
|
<article id="commenttemplate" class="comment"><div class="commentmeta"><span class="nickname">name</span><span class="commentdate">0000-00-00</span></div><div class="commentdata">c</div><button class="btn btn-default btn-sm"><?php echo I18n::_('Reply'); ?></button></article>
|
||||||
|
<div id="commenttailtemplate" class="comment"><button class="btn btn-default btn-sm"><?php echo I18n::_('Add comment'); ?></button></div>
|
||||||
|
<div id="replytemplate" class="reply hidden"><input type="text" id="nickname" class="form-control" title="<?php echo I18n::_('Optional nickname…'); ?>" placeholder="<?php echo I18n::_('Optional nickname…'); ?>" /><textarea id="replymessage" class="replymessage form-control" cols="80" rows="7"></textarea><br /><div id="replystatus" role="alert" class="statusmessage hidden alert"><span class="glyphicon" aria-hidden="true"></span> </div><button id="replybutton" class="btn btn-default btn-sm"><?php echo I18n::_('Post comment'); ?></button></div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
<section class="container">
|
<section class="container">
|
||||||
<div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true">
|
<div id="noscript" role="alert" class="nonworking alert alert-info noscript-hide"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true">
|
||||||
<span> <?php echo I18n::_('Loading…'); ?></span><br>
|
<span> <?php echo I18n::_('Loading…'); ?></span><br>
|
||||||
|
|
1
tst/.gitignore
vendored
1
tst/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/ConfigurationCombinationsTest.php
|
|
|
@ -1,2 +0,0 @@
|
||||||
Allow from none
|
|
||||||
Deny from all
|
|
|
@ -172,6 +172,7 @@ class Helper
|
||||||
*/
|
*/
|
||||||
public static function rmDir($path)
|
public static function rmDir($path)
|
||||||
{
|
{
|
||||||
|
if (is_dir($path)) {
|
||||||
$path .= DIRECTORY_SEPARATOR;
|
$path .= DIRECTORY_SEPARATOR;
|
||||||
$dir = dir($path);
|
$dir = dir($path);
|
||||||
while (false !== ($file = $dir->read())) {
|
while (false !== ($file = $dir->read())) {
|
||||||
|
@ -190,6 +191,7 @@ class Helper
|
||||||
throw new Exception('Error deleting directory "' . $path . '".');
|
throw new Exception('Error deleting directory "' . $path . '".');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a backup of the config file
|
* create a backup of the config file
|
||||||
|
|
|
@ -8,16 +8,26 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
private $_path;
|
private $_path;
|
||||||
|
|
||||||
|
private $_invalidPath;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
/* Setup Routine */
|
/* Setup Routine */
|
||||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||||
|
$this->_invalidPath = $this->_path . DIRECTORY_SEPARATOR . 'bar';
|
||||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||||
|
if (!is_dir($this->_path)) {
|
||||||
|
mkdir($this->_path);
|
||||||
|
}
|
||||||
|
if (!is_dir($this->_invalidPath)) {
|
||||||
|
mkdir($this->_invalidPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
/* Tear Down Routine */
|
/* Tear Down Routine */
|
||||||
|
chmod($this->_invalidPath, 0700);
|
||||||
Helper::rmDir($this->_path);
|
Helper::rmDir($this->_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +47,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does not yet exist');
|
$this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does not yet exist');
|
||||||
$this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()), 'store comment');
|
$this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()), 'store comment');
|
||||||
$this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment exists after storing it');
|
$this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment exists after storing it');
|
||||||
|
$this->assertFalse($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()), 'unable to store the same comment twice');
|
||||||
$comment = json_decode(json_encode(Helper::getComment()));
|
$comment = json_decode(json_encode(Helper::getComment()));
|
||||||
$comment->id = Helper::getCommentId();
|
$comment->id = Helper::getCommentId();
|
||||||
$comment->parentid = Helper::getPasteId();
|
$comment->parentid = Helper::getPasteId();
|
||||||
|
@ -99,10 +110,6 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException Exception
|
|
||||||
* @expectedExceptionCode 90
|
|
||||||
*/
|
|
||||||
public function testErrorDetection()
|
public function testErrorDetection()
|
||||||
{
|
{
|
||||||
$this->_model->delete(Helper::getPasteId());
|
$this->_model->delete(Helper::getPasteId());
|
||||||
|
@ -112,10 +119,6 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does still not exist');
|
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does still not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException Exception
|
|
||||||
* @expectedExceptionCode 90
|
|
||||||
*/
|
|
||||||
public function testCommentErrorDetection()
|
public function testCommentErrorDetection()
|
||||||
{
|
{
|
||||||
$this->_model->delete(Helper::getPasteId());
|
$this->_model->delete(Helper::getPasteId());
|
||||||
|
|
|
@ -4,14 +4,6 @@ use PrivateBin\Filter;
|
||||||
|
|
||||||
class FilterTest extends PHPUnit_Framework_TestCase
|
class FilterTest extends PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testFilterStripsSlashesDeeply()
|
|
||||||
{
|
|
||||||
$this->assertEquals(
|
|
||||||
array("f'oo", "b'ar", array("fo'o", "b'ar")),
|
|
||||||
Filter::stripslashesDeep(array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar")))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testFilterMakesTimesHumanlyReadable()
|
public function testFilterMakesTimesHumanlyReadable()
|
||||||
{
|
{
|
||||||
$this->assertEquals('5 minutes', Filter::formatHumanReadableTime('5min'));
|
$this->assertEquals('5 minutes', Filter::formatHumanReadableTime('5min'));
|
||||||
|
|
|
@ -98,6 +98,7 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
unlink($file);
|
||||||
$response = json_decode($content, true);
|
$response = json_decode($content, true);
|
||||||
$this->assertEquals(0, $response['status'], 'outputs status');
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
||||||
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputted paste ID matches input');
|
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputted paste ID matches input');
|
||||||
|
@ -132,6 +133,7 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
|
unlink($file);
|
||||||
$response = json_decode($content, true);
|
$response = json_decode($content, true);
|
||||||
$this->assertEquals(0, $response['status'], 'outputs status');
|
$this->assertEquals(0, $response['status'], 'outputs status');
|
||||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
||||||
|
@ -147,10 +149,9 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
$paste = $this->_model->read(Helper::getPasteId());
|
$paste = $this->_model->read(Helper::getPasteId());
|
||||||
$_POST = array(
|
$_POST = array(
|
||||||
'action' => 'delete',
|
'pasteid' => Helper::getPasteId(),
|
||||||
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste->meta->salt),
|
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste->meta->salt),
|
||||||
);
|
);
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
|
@ -82,6 +82,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
$comment = $paste->getComment(Helper::getPasteId());
|
$comment = $paste->getComment(Helper::getPasteId());
|
||||||
$comment->setData($commentData['data']);
|
$comment->setData($commentData['data']);
|
||||||
$comment->setNickname($commentData['meta']['nickname']);
|
$comment->setNickname($commentData['meta']['nickname']);
|
||||||
|
$comment->getParentId();
|
||||||
$comment->store();
|
$comment->store();
|
||||||
|
|
||||||
$comment = $paste->getComment(Helper::getPasteId(), Helper::getCommentId());
|
$comment = $paste->getComment(Helper::getPasteId(), Helper::getCommentId());
|
||||||
|
@ -189,6 +190,27 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
$this->assertFalse(Paste::isValidId('../bar/baz'), 'path attack');
|
$this->assertFalse(Paste::isValidId('../bar/baz'), 'path attack');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionCode 64
|
||||||
|
*/
|
||||||
|
public function testInvalidPaste()
|
||||||
|
{
|
||||||
|
$this->_model->getPaste(Helper::getPasteId())->delete();
|
||||||
|
$paste = $this->_model->getPaste(Helper::getPasteId());
|
||||||
|
$paste->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionCode 61
|
||||||
|
*/
|
||||||
|
public function testInvalidData()
|
||||||
|
{
|
||||||
|
$paste = $this->_model->getPaste();
|
||||||
|
$paste->setData('');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Exception
|
* @expectedException Exception
|
||||||
* @expectedExceptionCode 62
|
* @expectedExceptionCode 62
|
||||||
|
@ -199,6 +221,37 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
$paste->getComment(Helper::getPasteId());
|
$paste->getComment(Helper::getPasteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionCode 67
|
||||||
|
*/
|
||||||
|
public function testInvalidCommentDeletedPaste()
|
||||||
|
{
|
||||||
|
$pasteData = Helper::getPaste();
|
||||||
|
$paste = $this->_model->getPaste(Helper::getPasteId());
|
||||||
|
$paste->setData($pasteData['data']);
|
||||||
|
$paste->store();
|
||||||
|
|
||||||
|
$comment = $paste->getComment(Helper::getPasteId());
|
||||||
|
$paste->delete();
|
||||||
|
$comment->store();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionCode 68
|
||||||
|
*/
|
||||||
|
public function testInvalidCommentData()
|
||||||
|
{
|
||||||
|
$pasteData = Helper::getPaste();
|
||||||
|
$paste = $this->_model->getPaste(Helper::getPasteId());
|
||||||
|
$paste->setData($pasteData['data']);
|
||||||
|
$paste->store();
|
||||||
|
|
||||||
|
$comment = $paste->getComment(Helper::getPasteId());
|
||||||
|
$comment->store();
|
||||||
|
}
|
||||||
|
|
||||||
public function testExpiration()
|
public function testExpiration()
|
||||||
{
|
{
|
||||||
$pasteData = Helper::getPaste();
|
$pasteData = Helper::getPaste();
|
||||||
|
|
|
@ -140,21 +140,18 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
public function testHtaccess()
|
public function testHtaccess()
|
||||||
{
|
{
|
||||||
$this->reset();
|
$this->reset();
|
||||||
$dirs = array('cfg', 'lib');
|
$file = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||||
foreach ($dirs as $dir) {
|
|
||||||
$file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
|
|
||||||
@unlink($file);
|
@unlink($file);
|
||||||
}
|
|
||||||
|
$_POST = Helper::getPaste();
|
||||||
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||||
|
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||||
ob_start();
|
ob_start();
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
foreach ($dirs as $dir) {
|
|
||||||
$file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
|
$this->assertFileExists($file, 'htaccess recreated');
|
||||||
$this->assertFileExists(
|
|
||||||
$file,
|
|
||||||
"$dir htaccess recreated"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -739,10 +736,10 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertContains(
|
$this->assertRegExp(
|
||||||
'<div id="cipherdata" class="hidden">' .
|
'#<div id="cipherdata"[^>]*>' .
|
||||||
htmlspecialchars(Helper::getPasteAsJson(), ENT_NOQUOTES) .
|
preg_quote(htmlspecialchars(Helper::getPasteAsJson(), ENT_NOQUOTES)) .
|
||||||
'</div>',
|
'</div>#',
|
||||||
$content,
|
$content,
|
||||||
'outputs data correctly'
|
'outputs data correctly'
|
||||||
);
|
);
|
||||||
|
@ -760,7 +757,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs error correctly'
|
'outputs error correctly'
|
||||||
);
|
);
|
||||||
|
@ -778,7 +775,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist, has expired or has been deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs error correctly'
|
'outputs error correctly'
|
||||||
);
|
);
|
||||||
|
@ -798,7 +795,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist, has expired or has been deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs error correctly'
|
'outputs error correctly'
|
||||||
);
|
);
|
||||||
|
@ -818,10 +815,10 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
unset($burnPaste['meta']['salt']);
|
unset($burnPaste['meta']['salt']);
|
||||||
$this->assertContains(
|
$this->assertRegExp(
|
||||||
'<div id="cipherdata" class="hidden">' .
|
'#<div id="cipherdata"[^>]*>' .
|
||||||
htmlspecialchars(Helper::getPasteAsJson($burnPaste['meta']), ENT_NOQUOTES) .
|
preg_quote(htmlspecialchars(Helper::getPasteAsJson($burnPaste['meta']), ENT_NOQUOTES)) .
|
||||||
'</div>',
|
'</div>#',
|
||||||
$content,
|
$content,
|
||||||
'outputs data correctly'
|
'outputs data correctly'
|
||||||
);
|
);
|
||||||
|
@ -889,10 +886,10 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$meta['formatter'] = 'syntaxhighlighting';
|
$meta['formatter'] = 'syntaxhighlighting';
|
||||||
$this->assertContains(
|
$this->assertRegExp(
|
||||||
'<div id="cipherdata" class="hidden">' .
|
'#<div id="cipherdata"[^>]*>' .
|
||||||
htmlspecialchars(Helper::getPasteAsJson($meta), ENT_NOQUOTES) .
|
preg_quote(htmlspecialchars(Helper::getPasteAsJson($meta), ENT_NOQUOTES)) .
|
||||||
'</div>',
|
'</div>#',
|
||||||
$content,
|
$content,
|
||||||
'outputs data correctly'
|
'outputs data correctly'
|
||||||
);
|
);
|
||||||
|
@ -914,10 +911,10 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$oldPaste['meta']['formatter'] = 'plaintext';
|
$oldPaste['meta']['formatter'] = 'plaintext';
|
||||||
unset($oldPaste['meta']['salt']);
|
unset($oldPaste['meta']['salt']);
|
||||||
$this->assertContains(
|
$this->assertRegExp(
|
||||||
'<div id="cipherdata" class="hidden">' .
|
'#<div id="cipherdata"[^>]*>' .
|
||||||
htmlspecialchars(Helper::getPasteAsJson($oldPaste['meta']), ENT_NOQUOTES) .
|
preg_quote(htmlspecialchars(Helper::getPasteAsJson($oldPaste['meta']), ENT_NOQUOTES)) .
|
||||||
'</div>',
|
'</div>#',
|
||||||
$content,
|
$content,
|
||||||
'outputs data correctly'
|
'outputs data correctly'
|
||||||
);
|
);
|
||||||
|
@ -939,7 +936,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="status"[^>]*>.*Paste was properly deleted[^<]*</div>#s',
|
'#<div[^>]*id="status"[^>]*>.*Paste was properly deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs deleted status correctly'
|
'outputs deleted status correctly'
|
||||||
);
|
);
|
||||||
|
@ -960,7 +957,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs delete error correctly'
|
'outputs delete error correctly'
|
||||||
);
|
);
|
||||||
|
@ -980,7 +977,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist, has expired or has been deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs delete error correctly'
|
'outputs delete error correctly'
|
||||||
);
|
);
|
||||||
|
@ -1000,7 +997,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Wrong deletion token[^<]*</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Wrong deletion token\. Paste was not deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs delete error correctly'
|
'outputs delete error correctly'
|
||||||
);
|
);
|
||||||
|
@ -1047,7 +1044,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$response = json_decode($content, true);
|
$response = json_decode($content, true);
|
||||||
$this->assertEquals(1, $response['status'], 'outputs status');
|
$this->assertEquals(1, $response['status'], 'outputs status');
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste successfully deleted');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after failing to delete data');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1067,7 +1064,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
|
'#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist, has expired or has been deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs error correctly'
|
'outputs error correctly'
|
||||||
);
|
);
|
||||||
|
@ -1091,7 +1088,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]*id="status"[^>]*>.*Paste was properly deleted[^<]*</div>#s',
|
'#<div[^>]*id="status"[^>]*>.*Paste was properly deleted\.#s',
|
||||||
$content,
|
$content,
|
||||||
'outputs deleted status correctly'
|
'outputs deleted status correctly'
|
||||||
);
|
);
|
||||||
|
|
|
@ -63,6 +63,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||||
file_put_contents($file, 'data=foo');
|
file_put_contents($file, 'data=foo');
|
||||||
Request::setInputStream($file);
|
Request::setInputStream($file);
|
||||||
$request = new Request;
|
$request = new Request;
|
||||||
|
unlink($file);
|
||||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||||
$this->assertEquals('create', $request->getOperation());
|
$this->assertEquals('create', $request->getOperation());
|
||||||
$this->assertEquals('foo', $request->getParam('data'));
|
$this->assertEquals('foo', $request->getParam('data'));
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use PrivateBin\Persistence\ServerSalt;
|
||||||
use PrivateBin\Sjcl;
|
use PrivateBin\Sjcl;
|
||||||
|
|
||||||
class SjclTest extends PHPUnit_Framework_TestCase
|
class SjclTest extends PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testSjclValidatorValidatesCorrectly()
|
public function testSjclValidatorValidatesCorrectly()
|
||||||
{
|
{
|
||||||
|
ServerSalt::setPath(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data');
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->assertTrue(Sjcl::isValid($paste['data']), 'valid sjcl');
|
$this->assertTrue(Sjcl::isValid($paste['data']), 'valid sjcl');
|
||||||
$this->assertTrue(Sjcl::isValid($paste['attachment']), 'valid sjcl');
|
$this->assertTrue(Sjcl::isValid($paste['attachment']), 'valid sjcl');
|
||||||
|
|
|
@ -96,15 +96,15 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||||
public function testTemplateRendersCorrectly()
|
public function testTemplateRendersCorrectly()
|
||||||
{
|
{
|
||||||
foreach ($this->_content as $template => $content) {
|
foreach ($this->_content as $template => $content) {
|
||||||
$this->assertContains(
|
$this->assertRegExp(
|
||||||
'<div id="cipherdata" class="hidden">' .
|
'#<div[^>]+id="cipherdata"[^>]*>' .
|
||||||
htmlspecialchars(Helper::getPaste()['data'], ENT_NOQUOTES) .
|
preg_quote(htmlspecialchars(Helper::getPaste()['data'], ENT_NOQUOTES)) .
|
||||||
'</div>',
|
'</div>#',
|
||||||
$content,
|
$content,
|
||||||
$template . ': outputs data correctly'
|
$template . ': outputs data correctly'
|
||||||
);
|
);
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<div[^>]+id="errormessage"[^>]*>.*' . self::$error . '</div>#',
|
'#<div[^>]+id="errormessage"[^>]*>.*' . self::$error . '#s',
|
||||||
$content,
|
$content,
|
||||||
$template . ': outputs error correctly'
|
$template . ': outputs error correctly'
|
||||||
);
|
);
|
||||||
|
@ -119,7 +119,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||||
$template . ': checked discussion if configured'
|
$template . ': checked discussion if configured'
|
||||||
);
|
);
|
||||||
$this->assertRegExp(
|
$this->assertRegExp(
|
||||||
'#<[^>]+id="opendisc"[^>]*>#',
|
'#<[^>]+id="opendiscussionoption"[^>]*>#',
|
||||||
$content,
|
$content,
|
||||||
$template . ': discussions available if configured'
|
$template . ': discussions available if configured'
|
||||||
);
|
);
|
||||||
|
|
1
vendor/.htaccess
vendored
Normal file
1
vendor/.htaccess
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Require all denied
|
Loading…
Reference in New Issue
Block a user