Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1994826af8 | ||
|
|
ab950d6ffc | ||
|
|
b77e611a90 | ||
|
|
86f0284894 | ||
|
|
9bbe014dfe | ||
|
|
ad92c95500 | ||
|
|
d360190382 | ||
|
|
1737c8a7f6 | ||
|
|
cde262fd66 | ||
|
|
bd74689079 | ||
|
|
248942bdea | ||
|
|
d9f203300b | ||
|
|
aceabc969f | ||
|
|
dedc24d3a7 | ||
|
|
6e583e78e8 | ||
|
|
c012e83355 | ||
|
|
264355d185 | ||
|
|
fdbfd1ec60 | ||
|
|
7a8b27a255 | ||
|
|
ec4bfac98b | ||
|
|
c63ffe37c9 | ||
|
|
d2f3ce82c9 | ||
|
|
3e24a0b0a4 | ||
|
|
1a07e29ff4 | ||
|
|
1aa46a8928 | ||
|
|
d9083f8b5f | ||
|
|
23d558a6d7 | ||
|
|
665a5b7b12 | ||
|
|
1d73418969 | ||
|
|
f67b5e4cc4 | ||
|
|
ae2515444f | ||
|
|
463e77f0a5 | ||
|
|
d7b796b1a7 | ||
|
|
9b07d53077 | ||
|
|
8ee9b2bc31 | ||
|
|
c5989477a4 | ||
|
|
96d8a4e4f8 | ||
|
|
e865e11731 | ||
|
|
f0997bfe0d | ||
|
|
8b67dad456 | ||
|
|
53fdac1038 | ||
|
|
534a7602e6 | ||
|
|
30f329fe43 | ||
|
|
4ce39951a9 | ||
|
|
0e9eb34626 | ||
|
|
0ff299c425 | ||
|
|
6366258ce9 | ||
|
|
bca69a026e | ||
|
|
adc26ea42a | ||
|
|
84422b10c8 | ||
|
|
d05ad0f8f4 | ||
|
|
3f70ddaffa | ||
|
|
b16e8d84d7 | ||
|
|
5ee405d5a0 | ||
|
|
a5b9470636 | ||
|
|
16a3d54cb6 | ||
|
|
9677dcd978 | ||
|
|
17ea42f918 | ||
|
|
bd8915918d | ||
|
|
91db6773a0 | ||
|
|
f50680b61f | ||
|
|
3fb5d33333 | ||
|
|
f70bbb2660 | ||
|
|
589c1ac9bb | ||
|
|
d458fa1b89 | ||
|
|
dc2c99434f | ||
|
|
bbf36562d0 | ||
|
|
c458edf3e4 | ||
|
|
99c2aaef7a | ||
|
|
921096ca10 | ||
|
|
b0fbd6fa36 | ||
|
|
21bd67c44f | ||
|
|
4f142985a2 | ||
|
|
bfa89b44bc | ||
|
|
eba876e72b | ||
|
|
f1a7413e20 |
11
.rubocop.yml
11
.rubocop.yml
@@ -8,10 +8,12 @@ ClassVars:
|
||||
Enabled: false
|
||||
LineLength:
|
||||
Max: 120
|
||||
MethodLength:
|
||||
Max: 20
|
||||
Lint/UriEscapeUnescape:
|
||||
Enabled: false
|
||||
MethodLength:
|
||||
Max: 20
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Metrics/AbcSize:
|
||||
Max: 25
|
||||
Metrics/BlockLength:
|
||||
@@ -19,9 +21,14 @@ Metrics/BlockLength:
|
||||
- 'spec/**/*'
|
||||
Metrics/ClassLength:
|
||||
Max: 150
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 8
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
Style/FormatStringToken:
|
||||
Enabled: false
|
||||
Style/NumericPredicate:
|
||||
Exclude:
|
||||
- 'app/controllers/vuln_api.rb'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ruby:2.6.2-alpine3.9 AS builder
|
||||
FROM ruby:2.6.3-alpine AS builder
|
||||
LABEL maintainer="WPScan Team <team@wpscan.org>"
|
||||
|
||||
ARG BUNDLER_ARGS="--jobs=8 --without test development"
|
||||
@@ -19,7 +19,7 @@ RUN rake install --trace
|
||||
RUN chmod -R a+r /usr/local/bundle
|
||||
|
||||
|
||||
FROM ruby:2.6.2-alpine3.9
|
||||
FROM ruby:2.6.3-alpine
|
||||
LABEL maintainer="WPScan Team <team@wpscan.org>"
|
||||
|
||||
RUN adduser -h /wpscan -g WPScan -D wpscan
|
||||
|
||||
46
README.md
46
README.md
@@ -17,7 +17,6 @@
|
||||
<a href="https://badge.fury.io/rb/wpscan" target="_blank"><img src="https://badge.fury.io/rb/wpscan.svg"></a>
|
||||
<a href="https://travis-ci.org/wpscanteam/wpscan" target="_blank"><img src="https://travis-ci.org/wpscanteam/wpscan.svg?branch=master"></a>
|
||||
<a href="https://codeclimate.com/github/wpscanteam/wpscan" target="_blank"><img src="https://codeclimate.com/github/wpscanteam/wpscan/badges/gpa.svg"></a>
|
||||
<a href="https://www.patreon.com/wpscan" target="_blank"><img src="https://img.shields.io/badge/patreon-donate-green.svg"></a>
|
||||
</p>
|
||||
|
||||
# INSTALL
|
||||
@@ -78,41 +77,60 @@ docker run -it --rm wpscanteam/wpscan --url https://target.tld/ --enumerate u1-1
|
||||
|
||||
# Usage
|
||||
|
||||
```wpscan --url blog.tld``` This will scan the blog using default options with a good compromise between speed and accuracy. For example, the plugins will be checked passively but their version with a mixed detection mode (passively + aggressively). Potential config backup files will also be checked, along with other interesting findings. If a more stealthy approach is required, then ```wpscan --stealthy --url blog.tld``` can be used.
|
||||
```wpscan --url blog.tld``` This will scan the blog using default options with a good compromise between speed and accuracy. For example, the plugins will be checked passively but their version with a mixed detection mode (passively + aggressively). Potential config backup files will also be checked, along with other interesting findings.
|
||||
|
||||
If a more stealthy approach is required, then ```wpscan --stealthy --url blog.tld``` can be used.
|
||||
As a result, when using the ```--enumerate``` option, don't forget to set the ```--plugins-detection``` accordingly, as its default is 'passive'.
|
||||
|
||||
For more options, open a terminal and type ```wpscan --help``` (if you built wpscan from the source, you should type the command outside of the git repo)
|
||||
|
||||
The DB is located at ~/.wpscan/db
|
||||
|
||||
## Vulnerability Database
|
||||
|
||||
The WPScan CLI tool uses the [WPVulnDB API](https://wpvulndb.com/api) to retrieve WordPress vulnerability data in real time. For WPScan to retrieve the vulnerability data an API token must be supplied via the `--api-token` option, or via a configuration file, as discussed below. An API token can be obtained by registering an account on [WPVulnDB](https://wpvulndb.com/users/sign_up). Up to 50 API requests per day are given free of charge to registered users. Once the 50 API requests are exhausted, WPScan will continue to work as normal but without any vulnerability data. Users can upgrade to paid API usage to increase their API limits within their user profile on [WPVulnDB](https://wpvulndb.com/).
|
||||
|
||||
## Load CLI options from file/s
|
||||
|
||||
WPScan can load all options (including the --url) from configuration files, the following locations are checked (order: first to last):
|
||||
|
||||
- ~/.wpscan/cli_options.json
|
||||
- ~/.wpscan/cli_options.yml
|
||||
- pwd/.wpscan/cli_options.json
|
||||
- pwd/.wpscan/cli_options.yml
|
||||
- ~/.wpscan/scan.json
|
||||
- ~/.wpscan/scan.yml
|
||||
- pwd/.wpscan/scan.json
|
||||
- pwd/.wpscan/scan.yml
|
||||
|
||||
If those files exist, options from them will be loaded and overridden if found twice.
|
||||
If those files exist, options from the `cli_options` key will be loaded and overridden if found twice.
|
||||
|
||||
e.g:
|
||||
|
||||
~/.wpscan/cli_options.yml:
|
||||
~/.wpscan/scan.yml:
|
||||
|
||||
```yml
|
||||
proxy: 'http://127.0.0.1:8080'
|
||||
verbose: true
|
||||
cli_options:
|
||||
proxy: 'http://127.0.0.1:8080'
|
||||
verbose: true
|
||||
```
|
||||
|
||||
pwd/.wpscan/cli_options.yml:
|
||||
pwd/.wpscan/scan.yml:
|
||||
|
||||
```yml
|
||||
proxy: 'socks5://127.0.0.1:9090'
|
||||
url: 'http://target.tld'
|
||||
cli_options:
|
||||
proxy: 'socks5://127.0.0.1:9090'
|
||||
url: 'http://target.tld'
|
||||
```
|
||||
|
||||
Running ```wpscan``` in the current directory (pwd), is the same as ```wpscan -v --proxy socks5://127.0.0.1:9090 --url http://target.tld```
|
||||
|
||||
Enumerating usernames
|
||||
## Save API Token in a file
|
||||
|
||||
The feature mentioned above is useful to keep the API Token in a config file and not have to supply it via the CLI each time. To do so, create the ~/.wpscan/scan.yml file containing the below:
|
||||
|
||||
```yml
|
||||
cli_options:
|
||||
api_token: YOUR_API_TOKEN
|
||||
```
|
||||
|
||||
## Enumerating usernames
|
||||
|
||||
```shell
|
||||
wpscan --url https://target.tld/ --enumerate u
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'controllers/core'
|
||||
require_relative 'controllers/vuln_api'
|
||||
require_relative 'controllers/custom_directories'
|
||||
require_relative 'controllers/wp_version'
|
||||
require_relative 'controllers/main_theme'
|
||||
|
||||
@@ -7,15 +7,6 @@ module WPScan
|
||||
module Controller
|
||||
# Enumeration Controller
|
||||
class Enumeration < CMSScanner::Controller::Base
|
||||
def before_scan
|
||||
DB::DynamicFinders::Plugin.create_versions_finders
|
||||
DB::DynamicFinders::Theme.create_versions_finders
|
||||
|
||||
# Force the Garbage Collector to run due to the above method being
|
||||
# quite heavy in objects allocation
|
||||
GC.start
|
||||
end
|
||||
|
||||
def run
|
||||
enum = ParsedCli.enumerate || {}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ module WPScan
|
||||
end
|
||||
|
||||
# @return [ Array<OptParseValidator::OptBase> ]
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def cli_enum_choices
|
||||
[
|
||||
OptMultiChoices.new(
|
||||
@@ -19,10 +18,10 @@ module WPScan
|
||||
choices: {
|
||||
vp: OptBoolean.new(['--vulnerable-plugins']),
|
||||
ap: OptBoolean.new(['--all-plugins']),
|
||||
p: OptBoolean.new(['--plugins']),
|
||||
p: OptBoolean.new(['--popular-plugins']),
|
||||
vt: OptBoolean.new(['--vulnerable-themes']),
|
||||
at: OptBoolean.new(['--all-themes']),
|
||||
t: OptBoolean.new(['--themes']),
|
||||
t: OptBoolean.new(['--popular-themes']),
|
||||
tt: OptBoolean.new(['--timthumbs']),
|
||||
cb: OptBoolean.new(['--config-backups']),
|
||||
dbe: OptBoolean.new(['--db-exports']),
|
||||
@@ -45,7 +44,6 @@ module WPScan
|
||||
)
|
||||
]
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
# @return [ Array<OptParseValidator::OptBase> ]
|
||||
def cli_plugins_opts
|
||||
@@ -67,6 +65,11 @@ module WPScan
|
||||
'Use the supplied mode to check plugins versions instead of the --detection-mode ' \
|
||||
'or --plugins-detection modes.'],
|
||||
choices: %w[mixed passive aggressive], normalize: :to_sym, default: :mixed
|
||||
),
|
||||
OptInteger.new(
|
||||
['--plugins-threshold THRESHOLD',
|
||||
'Raise an error when the number of detected plugins via known locations reaches the threshold. ' \
|
||||
'Set to 0 to ignore the threshold.'], default: 100
|
||||
)
|
||||
]
|
||||
end
|
||||
@@ -91,6 +94,11 @@ module WPScan
|
||||
'Use the supplied mode to check themes versions instead of the --detection-mode ' \
|
||||
'or --themes-detection modes.'],
|
||||
choices: %w[mixed passive aggressive], normalize: :to_sym, advanced: true
|
||||
),
|
||||
OptInteger.new(
|
||||
['--themes-threshold THRESHOLD',
|
||||
'Raise an error when the number of detected themes via known locations reaches the threshold. ' \
|
||||
'Set to 0 to ignore the threshold.'], default: 20
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
@@ -56,12 +56,13 @@ module WPScan
|
||||
#
|
||||
# @return [ Boolean ] Wether or not to enumerate the plugins
|
||||
def enum_plugins?(opts)
|
||||
opts[:plugins] || opts[:all_plugins] || opts[:vulnerable_plugins]
|
||||
opts[:popular_plugins] || opts[:all_plugins] || opts[:vulnerable_plugins]
|
||||
end
|
||||
|
||||
def enum_plugins
|
||||
opts = default_opts('plugins').merge(
|
||||
list: plugins_list_from_opts(ParsedCli.options),
|
||||
threshold: ParsedCli.plugins_threshold,
|
||||
sort: true
|
||||
)
|
||||
|
||||
@@ -91,7 +92,7 @@ module WPScan
|
||||
|
||||
if opts[:enumerate][:all_plugins]
|
||||
DB::Plugins.all_slugs
|
||||
elsif opts[:enumerate][:plugins]
|
||||
elsif opts[:enumerate][:popular_plugins]
|
||||
DB::Plugins.popular_slugs
|
||||
else
|
||||
DB::Plugins.vulnerable_slugs
|
||||
@@ -102,12 +103,13 @@ module WPScan
|
||||
#
|
||||
# @return [ Boolean ] Wether or not to enumerate the themes
|
||||
def enum_themes?(opts)
|
||||
opts[:themes] || opts[:all_themes] || opts[:vulnerable_themes]
|
||||
opts[:popular_themes] || opts[:all_themes] || opts[:vulnerable_themes]
|
||||
end
|
||||
|
||||
def enum_themes
|
||||
opts = default_opts('themes').merge(
|
||||
list: themes_list_from_opts(ParsedCli.options),
|
||||
threshold: ParsedCli.themes_threshold,
|
||||
sort: true
|
||||
)
|
||||
|
||||
@@ -137,7 +139,7 @@ module WPScan
|
||||
|
||||
if opts[:enumerate][:all_themes]
|
||||
DB::Themes.all_slugs
|
||||
elsif opts[:enumerate][:themes]
|
||||
elsif opts[:enumerate][:popular_themes]
|
||||
DB::Themes.popular_slugs
|
||||
else
|
||||
DB::Themes.vulnerable_slugs
|
||||
|
||||
30
app/controllers/vuln_api.rb
Normal file
30
app/controllers/vuln_api.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Controller
|
||||
# Controller to handle the API token
|
||||
class VulnApi < CMSScanner::Controller::Base
|
||||
def cli_options
|
||||
[
|
||||
OptString.new(['--api-token TOKEN', 'The WPVulnDB API Token to display vulnerability data'])
|
||||
]
|
||||
end
|
||||
|
||||
def before_scan
|
||||
return unless ParsedCli.api_token
|
||||
|
||||
DB::VulnApi.token = ParsedCli.api_token
|
||||
|
||||
api_status = DB::VulnApi.status
|
||||
|
||||
raise Error::InvalidApiToken if api_status['error']
|
||||
raise Error::ApiLimitReached if api_status['requests_remaining'] == 0
|
||||
raise api_status['http_error'] if api_status['http_error']
|
||||
end
|
||||
|
||||
def after_scan
|
||||
output('status', status: DB::VulnApi.status, api_requests: WPScan.api_requests)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,9 +20,9 @@ module WPScan
|
||||
|
||||
enumerate(potential_urls(opts), opts.merge(check_full_response: 200)) do |res|
|
||||
if res.effective_url.end_with?('.zip')
|
||||
next unless res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
|
||||
next unless %r{\Aapplication/zip}i.match?(res.headers['Content-Type'])
|
||||
else
|
||||
next unless res.body =~ SQL_PATTERN
|
||||
next unless SQL_PATTERN.match?(res.body)
|
||||
end
|
||||
|
||||
found << Model::DbExport.new(res.request.url, found_by: DIRECT_ACCESS, confidence: 100)
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
def aggressive(_opts = {})
|
||||
path = 'installer-log.txt'
|
||||
|
||||
return unless target.head_and_get(path).body =~ /DUPLICATOR INSTALL-LOG/
|
||||
return unless /DUPLICATOR INSTALL-LOG/.match?(target.head_and_get(path).body)
|
||||
|
||||
Model::DuplicatorInstallerLog.new(
|
||||
target.url(path),
|
||||
|
||||
@@ -10,7 +10,7 @@ module WPScan
|
||||
pattern = %r{#{target.content_dir}/mu\-plugins/}i
|
||||
|
||||
target.in_scope_uris(target.homepage_res) do |uri|
|
||||
next unless uri.path =~ pattern
|
||||
next unless uri.path&.match?(pattern)
|
||||
|
||||
url = target.url('wp-content/mu-plugins/')
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ module WPScan
|
||||
path = 'wp-content/uploads/dump.sql'
|
||||
res = target.head_and_get(path, [200], get: { headers: { 'Range' => 'bytes=0-3000' } })
|
||||
|
||||
return unless res.body =~ SQL_PATTERN
|
||||
return unless SQL_PATTERN.match?(res.body)
|
||||
|
||||
Model::UploadSQLDump.new(
|
||||
target.url(path),
|
||||
|
||||
@@ -13,7 +13,7 @@ module WPScan
|
||||
|
||||
def valid_credentials?(response)
|
||||
response.code == 302 &&
|
||||
response.headers['Set-Cookie']&.any? { |cookie| cookie =~ /wordpress_logged_in_/i }
|
||||
[*response.headers['Set-Cookie']]&.any? { |cookie| cookie =~ /wordpress_logged_in_/i }
|
||||
end
|
||||
|
||||
def errored_response?(response)
|
||||
|
||||
@@ -8,7 +8,7 @@ module WPScan
|
||||
include CMSScanner::Finders::Finder::BreadthFirstDictionaryAttack
|
||||
|
||||
def login_request(username, password)
|
||||
target.method_call('wp.getUsersBlogs', [username, password])
|
||||
target.method_call('wp.getUsersBlogs', [username, password], cache_ttl: 0)
|
||||
end
|
||||
|
||||
def valid_credentials?(response)
|
||||
|
||||
@@ -19,7 +19,7 @@ module WPScan
|
||||
end
|
||||
end
|
||||
|
||||
target.multi_call(methods).run
|
||||
target.multi_call(methods, cache_ttl: 0).run
|
||||
end
|
||||
|
||||
# @param [ Array<Model::User> ] users
|
||||
|
||||
@@ -13,25 +13,15 @@ module WPScan
|
||||
def initialize(plugin)
|
||||
finders << PluginVersion::Readme.new(plugin)
|
||||
|
||||
load_specific_finders(plugin)
|
||||
create_and_load_dynamic_versions_finders(plugin)
|
||||
end
|
||||
|
||||
# Load the finders associated with the plugin
|
||||
# Create the dynamic version finders related to the plugin and register them
|
||||
#
|
||||
# @param [ Model::Plugin ] plugin
|
||||
def load_specific_finders(plugin)
|
||||
module_name = plugin.classify
|
||||
|
||||
return unless Finders::PluginVersion.constants.include?(module_name)
|
||||
|
||||
mod = Finders::PluginVersion.const_get(module_name)
|
||||
|
||||
mod.constants.each do |constant|
|
||||
c = mod.const_get(constant)
|
||||
|
||||
next unless c.is_a?(Class)
|
||||
|
||||
finders << c.new(plugin)
|
||||
def create_and_load_dynamic_versions_finders(plugin)
|
||||
DB::DynamicFinders::Plugin.create_versions_finders(plugin.slug).each do |finder|
|
||||
finders << finder.new(plugin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ module WPScan
|
||||
|
||||
# The target(plugin)#readme_url can't be used directly here
|
||||
# as if the --detection-mode is passive, it will always return nil
|
||||
Model::WpItem::READMES.each do |file|
|
||||
target.potential_readme_filenames.each do |file|
|
||||
res = target.head_and_get(file)
|
||||
|
||||
next unless res.code == 200 && !(numbers = version_numbers(res.body)).empty?
|
||||
@@ -52,7 +52,7 @@ module WPScan
|
||||
|
||||
number = Regexp.last_match[1]
|
||||
|
||||
number if number =~ /[0-9]+/
|
||||
number if /[0-9]+/.match?(number)
|
||||
end
|
||||
|
||||
# @param [ String ] body
|
||||
|
||||
@@ -15,7 +15,7 @@ module WPScan
|
||||
#
|
||||
# @return [ Plugin ] The detected plugin in the response, related to the config
|
||||
def process_response(opts, response, slug, klass, config)
|
||||
return unless response.body =~ config['pattern']
|
||||
return unless response.body&.match?(config['pattern'])
|
||||
|
||||
Model::Plugin.new(
|
||||
slug,
|
||||
|
||||
@@ -18,7 +18,7 @@ module WPScan
|
||||
response.html.xpath(config['xpath'] || '//comment()').each do |node|
|
||||
comment = node.text.to_s.strip
|
||||
|
||||
next unless comment =~ config['pattern']
|
||||
next unless comment&.match?(config['pattern'])
|
||||
|
||||
return Model::Plugin.new(
|
||||
slug,
|
||||
|
||||
@@ -21,6 +21,8 @@ module WPScan
|
||||
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
|
||||
found << Model::Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
||||
|
||||
raise Error::PluginsThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
|
||||
end
|
||||
|
||||
found
|
||||
|
||||
@@ -16,25 +16,15 @@ module WPScan
|
||||
ThemeVersion::Style.new(theme) <<
|
||||
ThemeVersion::WooFrameworkMetaGenerator.new(theme)
|
||||
|
||||
load_specific_finders(theme)
|
||||
create_and_load_dynamic_versions_finders(theme)
|
||||
end
|
||||
|
||||
# Load the finders associated with the theme
|
||||
# Create the dynamic version finders related to the theme and register them
|
||||
#
|
||||
# @param [ Model::Theme ] theme
|
||||
def load_specific_finders(theme)
|
||||
module_name = theme.classify
|
||||
|
||||
return unless Finders::ThemeVersion.constants.include?(module_name)
|
||||
|
||||
mod = Finders::ThemeVersion.const_get(module_name)
|
||||
|
||||
mod.constants.each do |constant|
|
||||
c = mod.const_get(constant)
|
||||
|
||||
next unless c.is_a?(Class)
|
||||
|
||||
finders << c.new(theme)
|
||||
def create_and_load_dynamic_versions_finders(theme)
|
||||
DB::DynamicFinders::Theme.create_versions_finders(theme.slug).each do |finder|
|
||||
finders << finder.new(theme)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,6 +21,8 @@ module WPScan
|
||||
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |_res, slug|
|
||||
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
||||
|
||||
raise Error::ThemesThresholdReached if opts[:threshold].positive? && found.size >= opts[:threshold]
|
||||
end
|
||||
|
||||
found
|
||||
|
||||
@@ -22,7 +22,7 @@ module WPScan
|
||||
found = []
|
||||
|
||||
enumerate(target_urls(opts), opts.merge(check_full_response: 400)) do |res|
|
||||
next unless res.body =~ /no image specified/i
|
||||
next unless /no image specified/i.match?(res.body)
|
||||
|
||||
found << Model::Timthumb.new(res.request.url, opts.merge(found_by: found_by, confidence: 100))
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@ module WPScan
|
||||
|
||||
return found if error.empty? # Protection plugin / error disabled
|
||||
|
||||
next unless error =~ /The password you entered for the username|Incorrect Password/i
|
||||
next unless /The password you entered for the username|Incorrect Password/i.match?(error)
|
||||
|
||||
found << Model::User.new(username, found_by: found_by, confidence: 100)
|
||||
end
|
||||
|
||||
@@ -15,9 +15,16 @@ module WPScan
|
||||
@uri = Addressable::URI.parse(blog.url(path_from_blog))
|
||||
end
|
||||
|
||||
# @return [ JSON ]
|
||||
# Retrieve the metadata from the vuln API if available (and a valid token is given),
|
||||
# or the local metadata db otherwise
|
||||
# @return [ Hash ]
|
||||
def metadata
|
||||
@metadata ||= db_data.empty? ? DB::Plugin.metadata_at(slug) : db_data
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def db_data
|
||||
@db_data ||= DB::Plugin.db_data(slug)
|
||||
@db_data ||= DB::VulnApi.plugin_data(slug)
|
||||
end
|
||||
|
||||
# @param [ Hash ] opts
|
||||
@@ -28,6 +35,11 @@ module WPScan
|
||||
|
||||
@version
|
||||
end
|
||||
|
||||
# @return [ Array<String> ]
|
||||
def potential_readme_filenames
|
||||
@potential_readme_filenames ||= [*(DB::DynamicFinders::Plugin.df_data.dig(slug, 'Readme', 'path') || super)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,9 +21,16 @@ module WPScan
|
||||
parse_style
|
||||
end
|
||||
|
||||
# Retrieve the metadata from the vuln API if available (and a valid token is given),
|
||||
# or the local metadata db otherwise
|
||||
# @return [ JSON ]
|
||||
def metadata
|
||||
@metadata ||= db_data.empty? ? DB::Theme.metadata_at(slug) : db_data
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def db_data
|
||||
@db_data ||= DB::Theme.db_data(slug)
|
||||
@db_data ||= DB::VulnApi.theme_data(slug)
|
||||
end
|
||||
|
||||
# @param [ Hash ] opts
|
||||
|
||||
@@ -9,6 +9,7 @@ module WPScan
|
||||
include CMSScanner::Target::Platform::PHP
|
||||
include CMSScanner::Target::Server::Generic
|
||||
|
||||
# Most common readme filenames, based on checking all public plugins and themes.
|
||||
READMES = %w[readme.txt README.txt README.md readme.md Readme.txt].freeze
|
||||
|
||||
attr_reader :uri, :slug, :detection_opts, :version_detection_opts, :blog, :path_from_blog, :db_data
|
||||
@@ -59,18 +60,18 @@ module WPScan
|
||||
|
||||
# @return [ String ]
|
||||
def latest_version
|
||||
@latest_version ||= db_data['latest_version'] ? Model::Version.new(db_data['latest_version']) : nil
|
||||
@latest_version ||= metadata['latest_version'] ? Model::Version.new(metadata['latest_version']) : nil
|
||||
end
|
||||
|
||||
# Not used anywhere ATM
|
||||
# @return [ Boolean ]
|
||||
def popular?
|
||||
@popular ||= db_data['popular']
|
||||
@popular ||= metadata['popular'] ? true : false
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def last_updated
|
||||
@last_updated ||= db_data['last_updated']
|
||||
@last_updated ||= metadata['last_updated']
|
||||
end
|
||||
|
||||
# @return [ Boolean ]
|
||||
@@ -117,7 +118,7 @@ module WPScan
|
||||
|
||||
return @readme_url unless @readme_url.nil?
|
||||
|
||||
READMES.each do |path|
|
||||
potential_readme_filenames.each do |path|
|
||||
t_url = url(path)
|
||||
|
||||
return @readme_url = t_url if Browser.forge_request(t_url, blog.head_or_get_params).run.code == 200
|
||||
@@ -126,6 +127,10 @@ module WPScan
|
||||
@readme_url = false
|
||||
end
|
||||
|
||||
def potential_readme_filenames
|
||||
@potential_readme_filenames ||= READMES
|
||||
end
|
||||
|
||||
# @param [ String ] path
|
||||
# @param [ Hash ] params The request params
|
||||
#
|
||||
|
||||
@@ -35,9 +35,16 @@ module WPScan
|
||||
@all_numbers.sort! { |a, b| Gem::Version.new(b) <=> Gem::Version.new(a) }
|
||||
end
|
||||
|
||||
# @return [ JSON ]
|
||||
# Retrieve the metadata from the vuln API if available (and a valid token is given),
|
||||
# or the local metadata db otherwise
|
||||
# @return [ Hash ]
|
||||
def metadata
|
||||
@metadata ||= db_data.empty? ? DB::Version.metadata_at(number) : db_data
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def db_data
|
||||
@db_data ||= DB::Version.db_data(number)
|
||||
@db_data ||= DB::VulnApi.wordpress_data(number)
|
||||
end
|
||||
|
||||
# @return [ Array<Vulnerability> ]
|
||||
@@ -55,12 +62,12 @@ module WPScan
|
||||
|
||||
# @return [ String ]
|
||||
def release_date
|
||||
@release_date ||= db_data['release_date'] || 'Unknown'
|
||||
@release_date ||= metadata['release_date'] || 'Unknown'
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def status
|
||||
@status ||= db_data['status'] || 'Unknown'
|
||||
@status ||= metadata['status'] || 'Unknown'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ _______________________________________________________________
|
||||
|
||||
WordPress Security Scanner by the WPScan Team
|
||||
Version <%= WPScan::VERSION %>
|
||||
Sponsored by Sucuri - https://sucuri.net
|
||||
<%= ' ' * ((63 - WPScan::DB::Sponsor.text.length)/2) + WPScan::DB::Sponsor.text %>
|
||||
@_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
|
||||
_______________________________________________________________
|
||||
|
||||
|
||||
13
app/views/cli/vuln_api/status.erb
Normal file
13
app/views/cli/vuln_api/status.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
<% unless @status.empty? -%>
|
||||
<% if @status['http_error'] -%>
|
||||
<%= critical_icon %> WPVulnDB API, <%= @status['http_error'].to_s %>
|
||||
<% else -%>
|
||||
<%= info_icon %> WPVulnDB API OK
|
||||
| Plan: <%= @status['plan'] %>
|
||||
| Requests Done (during the scan): <%= @api_requests %>
|
||||
| Requests Remaining: <%= @status['requests_remaining'] %>
|
||||
<% end -%>
|
||||
<% else -%>
|
||||
<%= warning_icon %> No WPVulnDB API Token given, as a result vulnerability data has not been output.
|
||||
<%= warning_icon %> You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/register.
|
||||
<% end -%>
|
||||
@@ -7,5 +7,5 @@
|
||||
"@erwan_lr",
|
||||
"@_FireFart_"
|
||||
],
|
||||
"sponsored_by": "Sucuri - https://sucuri.net"
|
||||
"sponsor": <%= WPScan::DB::Sponsor.text.to_json %>
|
||||
},
|
||||
|
||||
13
app/views/json/vuln_api/status.erb
Normal file
13
app/views/json/vuln_api/status.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
"vuln_api": {
|
||||
<% unless @status.empty? -%>
|
||||
<% if @status['http_error'] -%>
|
||||
"http_error": <%= @status['http_error'].to_s.to_json %>
|
||||
<% else -%>
|
||||
"plan": <%= @status['plan'].to_json %>,
|
||||
"requests_done_during_scan": <%= @api_requests.to_json %>,
|
||||
"requests_remaining": <%= @status['requests_remaining'].to_json %>
|
||||
<% end -%>
|
||||
<% else -%>
|
||||
"error": "No WPVulnDB API Token given, as a result vulnerability data has not been output.\nYou can get a free API token with 50 daily requests by registering at https://wpvulndb.com/register."
|
||||
<% end -%>
|
||||
},
|
||||
@@ -5,6 +5,7 @@ require 'wpscan'
|
||||
|
||||
WPScan::Scan.new do |s|
|
||||
s.controllers <<
|
||||
WPScan::Controller::VulnApi.new <<
|
||||
WPScan::Controller::CustomDirectories.new <<
|
||||
WPScan::Controller::InterestingFindings.new <<
|
||||
WPScan::Controller::WpVersion.new <<
|
||||
|
||||
@@ -7,6 +7,7 @@ require 'wpscan'
|
||||
report = MemoryProfiler.report(top: 15) do
|
||||
WPScan::Scan.new do |s|
|
||||
s.controllers <<
|
||||
WPScan::Controller::VulnApi.new <<
|
||||
WPScan::Controller::CustomDirectories.new <<
|
||||
WPScan::Controller::InterestingFindings.new <<
|
||||
WPScan::Controller::WpVersion.new <<
|
||||
|
||||
@@ -12,6 +12,7 @@ StackProf.run(mode: :cpu, out: '/tmp/stackprof-cpu.dump', interval: 500) do
|
||||
# require_relative 'wpscan' doesn't work
|
||||
WPScan::Scan.new do |s|
|
||||
s.controllers <<
|
||||
WPScan::Controller::VulnApi.new <<
|
||||
WPScan::Controller::CustomDirectories.new <<
|
||||
WPScan::Controller::InterestingFindings.new <<
|
||||
WPScan::Controller::WpVersion.new <<
|
||||
|
||||
@@ -13,7 +13,8 @@ require 'uri'
|
||||
require 'time'
|
||||
require 'readline'
|
||||
require 'securerandom'
|
||||
|
||||
# Monkey Patches/Fixes/Override
|
||||
require 'wpscan/typhoeus/response' # Adds a from_vuln_api? method
|
||||
# Custom Libs
|
||||
require 'wpscan/helper'
|
||||
require 'wpscan/db'
|
||||
@@ -38,12 +39,28 @@ module WPScan
|
||||
APP_DIR = Pathname.new(__FILE__).dirname.join('..', 'app').expand_path
|
||||
DB_DIR = Pathname.new(Dir.home).join('.wpscan', 'db')
|
||||
|
||||
Typhoeus.on_complete do |response|
|
||||
next if response.cached? || !response.from_vuln_api?
|
||||
|
||||
self.api_requests += 1
|
||||
end
|
||||
|
||||
# Override, otherwise it would be returned as 'wp_scan'
|
||||
#
|
||||
# @return [ String ]
|
||||
def self.app_name
|
||||
'wpscan'
|
||||
end
|
||||
|
||||
# @return [ Integer ]
|
||||
def self.api_requests
|
||||
@@api_requests ||= 0
|
||||
end
|
||||
|
||||
# @param [ Integer ] value
|
||||
def self.api_requests=(value)
|
||||
@@api_requests = value
|
||||
end
|
||||
end
|
||||
|
||||
require "#{WPScan::APP_DIR}/app"
|
||||
|
||||
@@ -7,7 +7,7 @@ module WPScan
|
||||
|
||||
# @return [ String ]
|
||||
def default_user_agent
|
||||
"WPScan v#{VERSION} (https://wpscan.org/)"
|
||||
@default_user_agent ||= "WPScan v#{VERSION} (https://wpscan.org/)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,9 +7,12 @@ require_relative 'db/plugins'
|
||||
require_relative 'db/themes'
|
||||
require_relative 'db/plugin'
|
||||
require_relative 'db/theme'
|
||||
require_relative 'db/sponsor'
|
||||
require_relative 'db/wp_version'
|
||||
require_relative 'db/fingerprints'
|
||||
|
||||
require_relative 'db/vuln_api'
|
||||
|
||||
require_relative 'db/dynamic_finders/base'
|
||||
require_relative 'db/dynamic_finders/plugin'
|
||||
require_relative 'db/dynamic_finders/theme'
|
||||
|
||||
@@ -5,18 +5,19 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Base
|
||||
# @return [ String ]
|
||||
def self.db_file
|
||||
@db_file ||= DB_DIR.join('dynamic_finders.yml').to_s
|
||||
def self.df_file
|
||||
@df_file ||= DB_DIR.join('dynamic_finders.yml').to_s
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
# true allows aliases to be loaded
|
||||
@db_data ||= YAML.safe_load(File.read(db_file), [Regexp], [], true)
|
||||
def self.all_df_data
|
||||
@all_df_data ||= YAML.safe_load(File.read(df_file), [Regexp])
|
||||
end
|
||||
|
||||
# @return [ Array<Symbol> ]
|
||||
def self.allowed_classes
|
||||
# The Readme is not put in there as it's not a Real DF, but rather using the DF system
|
||||
# to get the list of potential filenames for a given slug
|
||||
@allowed_classes ||= %i[Comment Xpath HeaderPattern BodyPattern JavascriptVar QueryParameter ConfigParser]
|
||||
end
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Plugin < Base
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['plugins'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['plugins'] || {}
|
||||
end
|
||||
|
||||
def self.version_finder_module
|
||||
@@ -21,7 +21,7 @@ module WPScan
|
||||
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
db_data.each do |slug, finders|
|
||||
df_data.each do |slug, finders|
|
||||
# Quite sure better can be done with some kind of logic statement in the select
|
||||
fs = if aggressive
|
||||
finders.reject { |_f, c| c['path'].nil? }
|
||||
@@ -48,7 +48,7 @@ module WPScan
|
||||
|
||||
@versions_finders_configs = {}
|
||||
|
||||
db_data.each do |slug, finders|
|
||||
df_data.each do |slug, finders|
|
||||
finders.each do |finder_name, config|
|
||||
next unless config.key?('version')
|
||||
|
||||
@@ -73,23 +73,33 @@ module WPScan
|
||||
version_finder_module.const_get(constant_name)
|
||||
end
|
||||
|
||||
def self.create_versions_finders
|
||||
versions_finders_configs.each do |slug, finders|
|
||||
mod = maybe_create_module(slug)
|
||||
# Create the dynamic finders related to the given slug, and return the created classes
|
||||
#
|
||||
# @param [ String ] slug
|
||||
#
|
||||
# @return [ Array<Class> ] The created classes
|
||||
def self.create_versions_finders(slug)
|
||||
created = []
|
||||
mod = maybe_create_module(slug)
|
||||
|
||||
finders.each do |finder_class, config|
|
||||
klass = config['class'] || finder_class
|
||||
versions_finders_configs[slug]&.each do |finder_class, config|
|
||||
klass = config['class'] || finder_class
|
||||
|
||||
# Instead of raising exceptions, skip unallowed/already defined finders
|
||||
# So that, when new DF configs are put in the .yml
|
||||
# users with old version of WPScan will still be able to scan blogs
|
||||
# when updating the DB but not the tool
|
||||
next if mod.constants.include?(finder_class.to_sym) ||
|
||||
!allowed_classes.include?(klass.to_sym)
|
||||
# Instead of raising exceptions, skip unallowed/already defined finders
|
||||
# So that, when new DF configs are put in the .yml
|
||||
# users with old version of WPScan will still be able to scan blogs
|
||||
# when updating the DB but not the tool
|
||||
|
||||
version_finder_super_class(klass).create_child_class(mod, finder_class.to_sym, config)
|
||||
end
|
||||
next unless allowed_classes.include?(klass.to_sym)
|
||||
|
||||
created << if mod.constants.include?(finder_class.to_sym)
|
||||
mod.const_get(finder_class.to_sym)
|
||||
else
|
||||
version_finder_super_class(klass).create_child_class(mod, finder_class.to_sym, config)
|
||||
end
|
||||
end
|
||||
|
||||
created
|
||||
end
|
||||
|
||||
# The idea here would be to check if the class exist in
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Theme < Plugin
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['themes'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['themes'] || {}
|
||||
end
|
||||
|
||||
def self.version_finder_module
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
module DynamicFinders
|
||||
class Wordpress < Base
|
||||
# @return [ Hash ]
|
||||
def self.db_data
|
||||
@db_data ||= super['wordpress'] || {}
|
||||
def self.df_data
|
||||
@df_data ||= all_df_data['wordpress'] || {}
|
||||
end
|
||||
|
||||
# @return [ Constant ]
|
||||
@@ -30,9 +30,9 @@ module WPScan
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
finders = if aggressive
|
||||
db_data.reject { |_f, c| c['path'].nil? }
|
||||
df_data.reject { |_f, c| c['path'].nil? }
|
||||
else
|
||||
db_data.select { |_f, c| c['path'].nil? }
|
||||
df_data.select { |_f, c| c['path'].nil? }
|
||||
end
|
||||
|
||||
finders.each do |finder_name, config|
|
||||
@@ -48,7 +48,7 @@ module WPScan
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.versions_finders_configs
|
||||
@versions_finders_configs ||= db_data.select { |_finder_name, config| config.key?('version') }
|
||||
@versions_finders_configs ||= df_data.select { |_finder_name, config| config.key?('version') }
|
||||
end
|
||||
|
||||
def self.create_versions_finders
|
||||
|
||||
@@ -4,9 +4,9 @@ module WPScan
|
||||
module DB
|
||||
# Plugin DB
|
||||
class Plugin < WpItem
|
||||
# @return [ String ]
|
||||
def self.db_file
|
||||
@db_file ||= DB_DIR.join('plugins.json').to_s
|
||||
# @return [ Hash ]
|
||||
def self.metadata
|
||||
@metadata ||= super['plugins'] || {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
# WP Plugins
|
||||
class Plugins < WpItems
|
||||
# @return [ JSON ]
|
||||
def self.db
|
||||
Plugin.db
|
||||
def self.metadata
|
||||
Plugin.metadata
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
16
lib/wpscan/db/sponsor.rb
Normal file
16
lib/wpscan/db/sponsor.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module DB
|
||||
class Sponsor
|
||||
# @return [ Hash ]
|
||||
def self.text
|
||||
@text ||= file_path.exist? ? File.read(file_path).chomp : ''
|
||||
end
|
||||
|
||||
def self.file_path
|
||||
@file_path ||= DB_DIR.join('sponsor.txt')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,9 +4,9 @@ module WPScan
|
||||
module DB
|
||||
# Theme DB
|
||||
class Theme < WpItem
|
||||
# @return [ String ]
|
||||
def self.db_file
|
||||
@db_file ||= DB_DIR.join('themes.json').to_s
|
||||
# @return [ Hash ]
|
||||
def self.metadata
|
||||
@metadata ||= super['themes'] || {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,8 +5,8 @@ module WPScan
|
||||
# WP Themes
|
||||
class Themes < WpItems
|
||||
# @return [ JSON ]
|
||||
def self.db
|
||||
Theme.db
|
||||
def self.metadata
|
||||
Theme.metadata
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,12 +7,15 @@ module WPScan
|
||||
class Updater
|
||||
# /!\ Might want to also update the Enumeration#cli_options when some filenames are changed here
|
||||
FILES = %w[
|
||||
plugins.json themes.json wordpresses.json
|
||||
metadata.json wp_fingerprints.json
|
||||
timthumbs-v3.txt config_backups.txt db_exports.txt
|
||||
dynamic_finders.yml wp_fingerprints.json LICENSE
|
||||
dynamic_finders.yml LICENSE sponsor.txt
|
||||
].freeze
|
||||
|
||||
OLD_FILES = %w[wordpress.db user-agents.txt dynamic_finders_01.yml].freeze
|
||||
OLD_FILES = %w[
|
||||
wordpress.db user-agents.txt dynamic_finders_01.yml
|
||||
wordpresses.json plugins.json themes.json
|
||||
].freeze
|
||||
|
||||
attr_reader :repo_directory
|
||||
|
||||
@@ -64,11 +67,12 @@ module WPScan
|
||||
# @return [ Hash ] The params for Typhoeus::Request
|
||||
# @note Those params can't be overriden by CLI options
|
||||
def request_params
|
||||
{
|
||||
@request_params ||= {
|
||||
timeout: 600,
|
||||
connecttimeout: 300,
|
||||
accept_encoding: 'gzip, deflate',
|
||||
cache_ttl: 0
|
||||
cache_ttl: 0,
|
||||
headers: { 'User-Agent' => Browser.instance.default_user_agent, 'Referer' => nil }
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
79
lib/wpscan/db/vuln_api.rb
Normal file
79
lib/wpscan/db/vuln_api.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module DB
|
||||
# WPVulnDB API
|
||||
class VulnApi
|
||||
NON_ERROR_CODES = [200, 401].freeze
|
||||
|
||||
class << self
|
||||
attr_accessor :token
|
||||
end
|
||||
|
||||
# @return [ Addressable::URI ]
|
||||
def self.uri
|
||||
@uri ||= Addressable::URI.parse('https://wpvulndb.com/api/v3/')
|
||||
end
|
||||
|
||||
# @param [ String ] path
|
||||
# @param [ Hash ] params
|
||||
#
|
||||
# @return [ Hash ]
|
||||
def self.get(path, params = {})
|
||||
return {} unless token
|
||||
|
||||
res = Browser.get(uri.join(path), params.merge(request_params))
|
||||
|
||||
return {} if res.code == 404 # This is for API inconsistencies when dots in path
|
||||
return JSON.parse(res.body) if NON_ERROR_CODES.include?(res.code)
|
||||
|
||||
raise Error::HTTP, res
|
||||
rescue Error::HTTP => e
|
||||
retries ||= 0
|
||||
|
||||
if (retries += 1) <= 3
|
||||
sleep(1)
|
||||
retry
|
||||
end
|
||||
|
||||
{ 'http_error' => e }
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.plugin_data(slug)
|
||||
get("plugins/#{slug}")&.dig(slug) || {}
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.theme_data(slug)
|
||||
get("themes/#{slug}")&.dig(slug) || {}
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.wordpress_data(version_number)
|
||||
get("wordpresses/#{version_number.tr('.', '')}")&.dig(version_number) || {}
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.status
|
||||
json = get('status', params: { version: WPScan::VERSION }, cache_ttl: 0)
|
||||
|
||||
json['requests_remaining'] = 'Unlimited' if json['requests_remaining'] == -1
|
||||
|
||||
json
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.request_params
|
||||
{
|
||||
headers: {
|
||||
'Host' => uri.host, # Reset in case user provided a --vhost for the target
|
||||
'Referer' => nil, # Removes referer set by the cmsscanner to the target url
|
||||
'User-Agent' => Browser.instance.default_user_agent,
|
||||
'Authorization' => "Token token=#{token}"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,14 +6,19 @@ module WPScan
|
||||
class WpItem
|
||||
# @param [ String ] identifier The plugin/theme slug or version number
|
||||
#
|
||||
# @return [ Hash ] The JSON data from the DB associated to the identifier
|
||||
def self.db_data(identifier)
|
||||
db[identifier] || {}
|
||||
# @return [ Hash ] The JSON data from the metadata associated to the identifier
|
||||
def self.metadata_at(identifier)
|
||||
metadata[identifier] || {}
|
||||
end
|
||||
|
||||
# @return [ JSON ]
|
||||
def self.db
|
||||
@db ||= read_json_file(db_file)
|
||||
def self.metadata
|
||||
@metadata ||= read_json_file(metadata_file)
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def self.metadata_file
|
||||
@metadata_file ||= DB_DIR.join('metadata.json').to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,17 +6,17 @@ module WPScan
|
||||
class WpItems
|
||||
# @return [ Array<String> ] The slug of all items
|
||||
def self.all_slugs
|
||||
db.keys
|
||||
metadata.keys
|
||||
end
|
||||
|
||||
# @return [ Array<String> ] The slug of all popular items
|
||||
def self.popular_slugs
|
||||
db.select { |_key, item| item['popular'] == true }.keys
|
||||
metadata.select { |_key, item| item['popular'] == true }.keys
|
||||
end
|
||||
|
||||
# @return [ Array<String> ] The slug of all vulnerable items
|
||||
def self.vulnerable_slugs
|
||||
db.reject { |_key, item| item['vulnerabilities'].empty? }.keys
|
||||
metadata.select { |_key, item| item['vulnerabilities'] == true }.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,9 +4,9 @@ module WPScan
|
||||
module DB
|
||||
# WP Version
|
||||
class Version < WpItem
|
||||
# @return [ String ]
|
||||
def self.db_file
|
||||
@db_file ||= DB_DIR.join('wordpresses.json').to_s
|
||||
# @return [ Hash ]
|
||||
def self.metadata
|
||||
@metadata ||= super['wordpress'] || {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,9 @@ module WPScan
|
||||
end
|
||||
end
|
||||
|
||||
require_relative 'errors/enumeration'
|
||||
require_relative 'errors/http'
|
||||
require_relative 'errors/update'
|
||||
require_relative 'errors/vuln_api'
|
||||
require_relative 'errors/wordpress'
|
||||
require_relative 'errors/xmlrpc'
|
||||
|
||||
21
lib/wpscan/errors/enumeration.rb
Normal file
21
lib/wpscan/errors/enumeration.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Error
|
||||
class PluginsThresholdReached < Standard
|
||||
def to_s
|
||||
"The number of plugins detected reached the threshold of #{ParsedCli.plugins_threshold} " \
|
||||
'which might indicate False Positive. It would be recommended to use the --exclude-content-based ' \
|
||||
'option to ignore the bad responses.'
|
||||
end
|
||||
end
|
||||
|
||||
class ThemesThresholdReached < Standard
|
||||
def to_s
|
||||
"The number of themes detected reached the threshold of #{ParsedCli.themes_threshold} " \
|
||||
'which might indicate False Positive. It would be recommended to use the --exclude-content-based ' \
|
||||
'option to ignore the bad responses.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
lib/wpscan/errors/vuln_api.rb
Normal file
20
lib/wpscan/errors/vuln_api.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Error
|
||||
# Error raised when the token given via --api-token is invalid
|
||||
class InvalidApiToken < Standard
|
||||
def to_s
|
||||
'The API token provided is invalid'
|
||||
end
|
||||
end
|
||||
|
||||
# Error raised when the number of API requests has been reached
|
||||
# currently not implemented on the API side
|
||||
class ApiLimitReached < Standard
|
||||
def to_s
|
||||
'Your API limit has been reached'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module Finders
|
||||
module DynamicFinder
|
||||
module Version
|
||||
# Version finder using Body Pattern method. Tipically used when the response is not
|
||||
# Version finder using Body Pattern method. Typically used when the response is not
|
||||
# an HTML doc and Xpath can't be used
|
||||
class BodyPattern < Finders::DynamicFinder::Version::Finder
|
||||
# @return [ Hash ]
|
||||
@@ -16,7 +16,7 @@ module WPScan
|
||||
# @param [ Hash ] opts
|
||||
# @return [ Version ]
|
||||
def find(response, _opts = {})
|
||||
return unless response.body =~ self.class::PATTERN
|
||||
return unless response.code != 404 && response.body =~ self.class::PATTERN
|
||||
|
||||
create_version(
|
||||
Regexp.last_match[:v],
|
||||
|
||||
@@ -6,13 +6,15 @@ rescue StandardError => e
|
||||
raise "JSON parsing error in #{file} #{e}"
|
||||
end
|
||||
|
||||
# @return [ Symbol ]
|
||||
# Sanitize and classify a slug
|
||||
# @note As a class can not start with a digit or underscore, a D_ is
|
||||
# put as a prefix in such case. Ugly but well :x
|
||||
# Not only used to classify slugs though, but Dynamic Finder names as well
|
||||
# put as a prefix in such case. Ugly but well :x
|
||||
# Not only used to classify slugs though, but Dynamic Finder names as well
|
||||
#
|
||||
# @return [ Symbol ]
|
||||
def classify_slug(slug)
|
||||
classified = slug.to_s.tr('-', '_').camelize.to_s
|
||||
classified = "D_#{classified}" if classified[0] =~ /\d/
|
||||
classified = slug.to_s.gsub(/[^a-z\d\-]/i, '-').gsub(/\-{1,}/, '_').camelize.to_s
|
||||
classified = "D_#{classified}" if /\d/.match?(classified[0])
|
||||
|
||||
classified.to_sym
|
||||
end
|
||||
|
||||
@@ -29,7 +29,7 @@ module WPScan
|
||||
end
|
||||
|
||||
homepage_res.html.css('meta[name="generator"]').each do |node|
|
||||
return true if node['content'] =~ /wordpress/i
|
||||
return true if /wordpress/i.match?(node['content'])
|
||||
end
|
||||
|
||||
return true unless comments_from_page(/wordpress/i, homepage_res).empty?
|
||||
@@ -109,6 +109,7 @@ module WPScan
|
||||
Browser.instance.forge_request(
|
||||
login_url,
|
||||
method: :post,
|
||||
cache_ttl: 0,
|
||||
body: { log: username, pwd: password }
|
||||
)
|
||||
end
|
||||
|
||||
@@ -99,20 +99,19 @@ module WPScan
|
||||
|
||||
# @return [ String, False ] String of the sub_dir found, false otherwise
|
||||
# @note: nil can not be returned here, otherwise if there is no sub_dir
|
||||
# the check would be done each time
|
||||
# the check would be done each time, which would make enumeration of
|
||||
# long list of items very slow to generate
|
||||
def sub_dir
|
||||
unless @sub_dir
|
||||
# url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
|
||||
return @sub_dir unless @sub_dir.nil?
|
||||
|
||||
in_scope_uris(homepage_res) do |uri|
|
||||
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
|
||||
end
|
||||
# url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
|
||||
|
||||
@sub_dir = false
|
||||
in_scope_uris(homepage_res) do |uri|
|
||||
return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
|
||||
end
|
||||
|
||||
@sub_dir
|
||||
@sub_dir = false
|
||||
end
|
||||
|
||||
# Override of the WebSite#url to consider the custom WP directories
|
||||
|
||||
13
lib/wpscan/typhoeus/response.rb
Normal file
13
lib/wpscan/typhoeus/response.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Typhoeus
|
||||
# Custom Response class
|
||||
class Response
|
||||
# @note: Ignores requests done to the /status endpoint of the API
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def from_vuln_api?
|
||||
effective_url.start_with?(WPScan::DB::VulnApi.uri.to_s) && !effective_url.include?('/status')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
# Version
|
||||
module WPScan
|
||||
VERSION = '3.5.5'
|
||||
VERSION = '3.7.1'
|
||||
end
|
||||
|
||||
@@ -70,8 +70,8 @@ describe WPScan::Controller::Enumeration do
|
||||
it 'contains the correct options' do
|
||||
expect(controller.cli_options.map(&:to_sym)).to eql(
|
||||
%i[enumerate exclude_content_based
|
||||
plugins_list plugins_detection plugins_version_all plugins_version_detection
|
||||
themes_list themes_detection themes_version_all themes_version_detection
|
||||
plugins_list plugins_detection plugins_version_all plugins_version_detection plugins_threshold
|
||||
themes_list themes_detection themes_version_all themes_version_detection themes_threshold
|
||||
timthumbs_list timthumbs_detection
|
||||
config_backups_list config_backups_detection
|
||||
db_exports_list db_exports_detection
|
||||
@@ -102,15 +102,6 @@ describe WPScan::Controller::Enumeration do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#before_scan' do
|
||||
it 'creates the Dynamic Finders' do
|
||||
expect(WPScan::DB::DynamicFinders::Plugin).to receive(:create_versions_finders)
|
||||
expect(WPScan::DB::DynamicFinders::Theme).to receive(:create_versions_finders)
|
||||
|
||||
controller.before_scan
|
||||
end
|
||||
end
|
||||
|
||||
describe '#run' do
|
||||
context 'when no :enumerate' do
|
||||
before do
|
||||
|
||||
93
spec/app/controllers/vuln_api_spec.rb
Normal file
93
spec/app/controllers/vuln_api_spec.rb
Normal file
@@ -0,0 +1,93 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe WPScan::Controller::VulnApi do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
let(:cli_args) { "--url #{target_url}" }
|
||||
|
||||
before do
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
its(:cli_options) { should_not be_empty }
|
||||
its(:cli_options) { should be_a Array }
|
||||
|
||||
it 'contains to correct options' do
|
||||
expect(controller.cli_options.map(&:to_sym)).to eq %i[api_token]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#before_scan' do
|
||||
context 'when no --api-token provided' do
|
||||
its(:before_scan) { should be nil }
|
||||
end
|
||||
|
||||
context 'when --api-token given' do
|
||||
let(:cli_args) { "#{super()} --api-token token" }
|
||||
|
||||
context 'when the token is invalid' do
|
||||
before { expect(WPScan::DB::VulnApi).to receive(:status).and_return('error' => 'HTTP Token: Access denied.') }
|
||||
|
||||
it 'raise an InvalidApiToken error' do
|
||||
expect { controller.before_scan }.to raise_error(WPScan::Error::InvalidApiToken)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the token is valid' do
|
||||
context 'when the limit has been reached' do
|
||||
before do
|
||||
expect(WPScan::DB::VulnApi)
|
||||
.to receive(:status)
|
||||
.and_return('success' => true, 'plan' => 'free', 'requests_remaining' => 0)
|
||||
end
|
||||
|
||||
it 'raises an ApiLimitReached error' do
|
||||
expect { controller.before_scan }.to raise_error(WPScan::Error::ApiLimitReached)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a HTTP error, like a timeout' do
|
||||
before do
|
||||
expect(WPScan::DB::VulnApi)
|
||||
.to receive(:status)
|
||||
.and_return(
|
||||
'http_error' => WPScan::Error::HTTP.new(
|
||||
Typhoeus::Response.new(effective_url: 'mock-url', return_code: 28)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it 'raises an HTTP error' do
|
||||
expect { controller.before_scan }
|
||||
.to raise_error(WPScan::Error::HTTP, 'HTTP Error: mock-url (Timeout was reached)')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the token is valid and no HTTP error' do
|
||||
before do
|
||||
expect(WPScan::DB::VulnApi)
|
||||
.to receive(:status)
|
||||
.and_return('success' => true, 'plan' => 'free', 'requests_remaining' => requests)
|
||||
end
|
||||
|
||||
context 'when limited requests' do
|
||||
let(:requests) { 100 }
|
||||
|
||||
it 'does not raise an error' do
|
||||
expect { controller.before_scan }.to_not raise_error
|
||||
end
|
||||
|
||||
context 'when unlimited requests' do
|
||||
let(:requests) { 'Unlimited' }
|
||||
|
||||
it 'does not raise an error' do
|
||||
expect { controller.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
61
spec/app/finders/passwords/wp_login_spec.rb
Normal file
61
spec/app/finders/passwords/wp_login_spec.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe WPScan::Finders::Passwords::WpLogin do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#valid_credentials?' do
|
||||
context 'when a non 302' do
|
||||
it 'returns false' do
|
||||
expect(finder.valid_credentials?(Typhoeus::Response.new(code: 200, headers: {}))).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a 302' do
|
||||
let(:response) { Typhoeus::Response.new(code: 302, headers: headers) }
|
||||
|
||||
context 'when no cookies set' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns false' do
|
||||
expect(finder.valid_credentials?(response)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no logged_in cookie set' do
|
||||
context 'when only one cookie set' do
|
||||
let(:headers) { 'Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/' }
|
||||
|
||||
it 'returns false' do
|
||||
expect(finder.valid_credentials?(response)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when multiple cookies set' do
|
||||
let(:headers) do
|
||||
"Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/\r\n" \
|
||||
'Set-Cookie: something=value; path=/'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(finder.valid_credentials?(response)).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged_in cookie set' do
|
||||
let(:headers) do
|
||||
"Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/\r\r" \
|
||||
"Set-Cookie: wordpress_xxx=yyy; path=/wp-content/plugins; httponly\r\n" \
|
||||
"Set-Cookie: wordpress_xxx=yyy; path=/wp-admin; httponly\r\n" \
|
||||
'Set-Cookie: wordpress_logged_in_xxx=yyy; path=/; httponly'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(finder.valid_credentials?(response)).to eql true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# If this file is tested alone (rspec path-to-this-file), then there will be an error about
|
||||
# constants not being intilialized. This is due to the Dynamic Finders.
|
||||
|
||||
describe WPScan::Finders::PluginVersion::Base do
|
||||
subject(:plugin_version) { described_class.new(plugin) }
|
||||
let(:plugin) { WPScan::Model::Plugin.new(slug, target) }
|
||||
@@ -15,7 +12,7 @@ describe WPScan::Finders::PluginVersion::Base do
|
||||
expect(plugin_version.finders.map { |f| f.class.to_s.demodulize }).to match_array @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
context 'when no related dynamic finders' do
|
||||
let(:slug) { 'spec' }
|
||||
|
||||
it 'contains the default finders' do
|
||||
@@ -25,19 +22,13 @@ describe WPScan::Finders::PluginVersion::Base do
|
||||
|
||||
# Dynamic Version Finders are not tested here, they are in
|
||||
# spec/lib/finders/dynamic_finder/plugin_versions_spec
|
||||
context 'when specific finders' do
|
||||
let(:specific) do
|
||||
{
|
||||
# None so far
|
||||
}
|
||||
end
|
||||
|
||||
context 'when dynamic finders' do
|
||||
WPScan::DB::DynamicFinders::Plugin.versions_finders_configs.each do |plugin_slug, configs|
|
||||
context "when #{plugin_slug} plugin" do
|
||||
let(:slug) { plugin_slug }
|
||||
|
||||
it 'contains the expected finders (default + specific + the dynamic ones)' do
|
||||
@expected = default_finders + [*specific[plugin_slug]] + configs.keys
|
||||
it 'contains the expected finders (default + the dynamic ones)' do
|
||||
@expected = default_finders + configs.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,20 +13,21 @@ describe WPScan::Finders::ThemeVersion::Base do
|
||||
expect(theme_version.finders.map { |f| f.class.to_s.demodulize }).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
context 'when no related dynamic finders' do
|
||||
it 'contains the default finders' do
|
||||
@expected = default_finders
|
||||
end
|
||||
end
|
||||
|
||||
context 'when specific finders' do
|
||||
{
|
||||
}.each do |theme_slug, specific_finders|
|
||||
# Dynamic Version Finders are not tested here, they are in
|
||||
# spec/lib/finders/dynamic_finder/theme_versions_spec
|
||||
context 'when dynamic finders' do
|
||||
WPScan::DB::DynamicFinders::Theme.versions_finders_configs.each do |theme_slug, configs|
|
||||
context "when #{theme_slug} theme" do
|
||||
let(:slug) { theme_slug }
|
||||
|
||||
it 'contains the expected finders' do
|
||||
@expected = default_finders + specific_finders
|
||||
it 'contains the expected finders (default + the dynamic ones)' do
|
||||
@expected = default_finders + configs.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,25 +60,60 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'potential_readme_filenames' do
|
||||
context 'when not set in the DF file' do
|
||||
its(:potential_readme_filenames) { should eql described_class::READMES }
|
||||
end
|
||||
|
||||
context 'when set in the DF file' do
|
||||
context 'as a string' do
|
||||
let(:slug) { 'photoblocks-grid-gallery' }
|
||||
|
||||
its(:potential_readme_filenames) { should eql %w[README.txt] }
|
||||
end
|
||||
|
||||
context 'as an array' do
|
||||
let(:slug) { 'customerlabs-actionrecorder' }
|
||||
|
||||
its(:potential_readme_filenames) { should eql %w[Readme.txt Readme.md] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#latest_version, #last_updated, #popular' do
|
||||
context 'when none' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
before { allow(plugin).to receive(:db_data).and_return(db_data) }
|
||||
|
||||
context 'when no db_data and no metadata' do
|
||||
let(:slug) { 'not-known' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
its(:latest_version) { should be_nil }
|
||||
its(:last_updated) { should be_nil }
|
||||
its(:popular?) { should be false }
|
||||
end
|
||||
|
||||
context 'when values' do
|
||||
context 'when no db_data but metadata' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
its(:latest_version) { should eql WPScan::Model::Version.new('2.0') }
|
||||
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z' }
|
||||
its(:popular?) { should be true }
|
||||
end
|
||||
|
||||
context 'when db_data' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { vuln_api_data_for('plugins/no-vulns-popular') }
|
||||
|
||||
its(:latest_version) { should eql WPScan::Model::Version.new('2.1') }
|
||||
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z-via-api' }
|
||||
its(:popular?) { should be true }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#outdated?' do
|
||||
before { allow(plugin).to receive(:db_data).and_return({}) }
|
||||
|
||||
context 'when last_version' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
|
||||
@@ -96,13 +131,13 @@ describe WPScan::Model::Plugin do
|
||||
.and_return(WPScan::Model::Version.new(version_number))
|
||||
end
|
||||
|
||||
context 'when version < last_version' do
|
||||
context 'when version < latest_version' do
|
||||
let(:version_number) { '1.2' }
|
||||
|
||||
its(:outdated?) { should eql true }
|
||||
end
|
||||
|
||||
context 'when version >= last_version' do
|
||||
context 'when version >= latest_version' do
|
||||
let(:version_number) { '3.0' }
|
||||
|
||||
its(:outdated?) { should eql false }
|
||||
@@ -110,7 +145,7 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no last_version' do
|
||||
context 'when no latest_version' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
|
||||
context 'when no version' do
|
||||
@@ -133,13 +168,16 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
|
||||
describe '#vulnerabilities' do
|
||||
before { allow(plugin).to receive(:db_data).and_return(db_data) }
|
||||
|
||||
after do
|
||||
expect(plugin.vulnerabilities).to eq @expected
|
||||
expect(plugin.vulnerable?).to eql @expected.empty? ? false : true
|
||||
end
|
||||
|
||||
context 'when plugin not in the DB' do
|
||||
let(:slug) { 'not-in-db' }
|
||||
let(:slug) { 'not-in-db' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
it 'returns an empty array' do
|
||||
@expected = []
|
||||
@@ -148,7 +186,8 @@ describe WPScan::Model::Plugin do
|
||||
|
||||
context 'when in the DB' do
|
||||
context 'when no vulnerabilities' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { vuln_api_data_for('plugins/no-vulns-popular') }
|
||||
|
||||
it 'returns an empty array' do
|
||||
@expected = []
|
||||
@@ -156,11 +195,13 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
|
||||
context 'when vulnerabilities' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
let(:db_data) { vuln_api_data_for('plugins/vulnerable-not-popular') }
|
||||
|
||||
let(:all_vulns) do
|
||||
[
|
||||
WPScan::Vulnerability.new(
|
||||
'First Vuln',
|
||||
'First Vuln <= 6.3.10 - LFI',
|
||||
{ wpvulndb: '1' },
|
||||
'LFI',
|
||||
'6.3.10'
|
||||
|
||||
@@ -86,8 +86,179 @@ describe WPScan::Model::Theme do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#latest_version, #last_updated, #popular' do
|
||||
before do
|
||||
stub_request(:get, /.*\.css\z/)
|
||||
allow(theme).to receive(:db_data).and_return(db_data)
|
||||
end
|
||||
|
||||
context 'when no db_data and no metadata' do
|
||||
let(:slug) { 'not-known' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
its(:latest_version) { should be_nil }
|
||||
its(:last_updated) { should be_nil }
|
||||
its(:popular?) { should be false }
|
||||
end
|
||||
|
||||
context 'when no db_data but metadata' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
its(:latest_version) { should eql WPScan::Model::Version.new('2.0') }
|
||||
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z' }
|
||||
its(:popular?) { should be true }
|
||||
end
|
||||
|
||||
context 'when db_data' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { vuln_api_data_for('themes/no-vulns-popular') }
|
||||
|
||||
its(:latest_version) { should eql WPScan::Model::Version.new('2.2') }
|
||||
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z-via-api' }
|
||||
its(:popular?) { should be true }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#outdated?' do
|
||||
before do
|
||||
stub_request(:get, /.*\.css\z/)
|
||||
allow(theme).to receive(:db_data).and_return({})
|
||||
end
|
||||
|
||||
context 'when last_version' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
|
||||
context 'when no version' do
|
||||
before { expect(theme).to receive(:version).at_least(1).and_return(nil) }
|
||||
|
||||
its(:outdated?) { should eql false }
|
||||
end
|
||||
|
||||
context 'when version' do
|
||||
before do
|
||||
expect(theme)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new(version_number))
|
||||
end
|
||||
|
||||
context 'when version < latest_version' do
|
||||
let(:version_number) { '1.2' }
|
||||
|
||||
its(:outdated?) { should eql true }
|
||||
end
|
||||
|
||||
context 'when version >= latest_version' do
|
||||
let(:version_number) { '3.0' }
|
||||
|
||||
its(:outdated?) { should eql false }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no latest_version' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
|
||||
context 'when no version' do
|
||||
before { expect(theme).to receive(:version).at_least(1).and_return(nil) }
|
||||
|
||||
its(:outdated?) { should eql false }
|
||||
end
|
||||
|
||||
context 'when version' do
|
||||
before do
|
||||
expect(theme)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new('1.0'))
|
||||
end
|
||||
|
||||
its(:outdated?) { should eql false }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#vulnerabilities' do
|
||||
xit
|
||||
before do
|
||||
stub_request(:get, /.*\.css\z/)
|
||||
allow(theme).to receive(:db_data).and_return(db_data)
|
||||
end
|
||||
|
||||
after do
|
||||
expect(theme.vulnerabilities).to eq @expected
|
||||
expect(theme.vulnerable?).to eql @expected.empty? ? false : true
|
||||
end
|
||||
|
||||
context 'when theme not in the DB' do
|
||||
let(:slug) { 'not-in-db' }
|
||||
let(:db_data) { {} }
|
||||
|
||||
it 'returns an empty array' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when in the DB' do
|
||||
context 'when no vulnerabilities' do
|
||||
let(:slug) { 'no-vulns-popular' }
|
||||
let(:db_data) { vuln_api_data_for('themes/no-vulns-popular') }
|
||||
|
||||
it 'returns an empty array' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when vulnerabilities' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
let(:db_data) { vuln_api_data_for('themes/vulnerable-not-popular') }
|
||||
|
||||
let(:all_vulns) do
|
||||
[
|
||||
WPScan::Vulnerability.new(
|
||||
'First Vuln',
|
||||
{ wpvulndb: '1' },
|
||||
'LFI',
|
||||
'6.3.10'
|
||||
),
|
||||
WPScan::Vulnerability.new('No Fixed In', wpvulndb: '2')
|
||||
]
|
||||
end
|
||||
|
||||
context 'when no theme version' do
|
||||
before { expect(theme).to receive(:version).at_least(1).and_return(false) }
|
||||
|
||||
it 'returns all the vulnerabilities' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when theme version' do
|
||||
before do
|
||||
expect(theme)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new(number))
|
||||
end
|
||||
|
||||
context 'when < to a fixed_in' do
|
||||
let(:number) { '5.0' }
|
||||
|
||||
it 'returns it' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when >= to a fixed_in' do
|
||||
let(:number) { '6.3.10' }
|
||||
|
||||
it 'does not return it ' do
|
||||
@expected = [all_vulns.last]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#parent_theme' do
|
||||
|
||||
@@ -40,11 +40,13 @@ describe WPScan::Model::WpVersion do
|
||||
|
||||
describe '#vulnerabilities' do
|
||||
subject(:version) { described_class.new(number) }
|
||||
before { allow(version).to receive(:db_data).and_return(db_data) }
|
||||
|
||||
context 'when no vulns' do
|
||||
let(:number) { '4.4' }
|
||||
let(:db_data) { { 'vulnerabilities' => [] } }
|
||||
|
||||
its(:vulnerabilities) { should eql([]) }
|
||||
its(:vulnerabilities) { should be_empty }
|
||||
end
|
||||
|
||||
context 'when vulnerable' do
|
||||
@@ -53,13 +55,30 @@ describe WPScan::Model::WpVersion do
|
||||
expect(version).to be_vulnerable
|
||||
end
|
||||
|
||||
let(:all_vulns) do
|
||||
[
|
||||
WPScan::Vulnerability.new(
|
||||
'WP 3.8.1 - Vuln 1',
|
||||
{ wpvulndb: '1' },
|
||||
'SQLI'
|
||||
),
|
||||
WPScan::Vulnerability.new(
|
||||
'WP 3.8.1 - Vuln 2',
|
||||
{ url: %w[url-2 url-3], osvdb: %w[10], cve: %w[2014-0166], wpvulndb: '2' },
|
||||
nil,
|
||||
'3.8.2'
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
context 'when a signle vuln' do
|
||||
let(:number) { '3.8' }
|
||||
let(:number) { '3.8.1' }
|
||||
let(:db_data) { vuln_api_data_for('wordpresses/38') }
|
||||
|
||||
it 'returns the expected result' do
|
||||
@expected = [WPScan::Vulnerability.new(
|
||||
'WP 3.8 - Vuln 1',
|
||||
{ url: %w[url-4], osvdb: %w[11], wpvulndb: '3' },
|
||||
{ url: %w[url-4], wpvulndb: '3' },
|
||||
'AUTHBYPASS'
|
||||
)]
|
||||
end
|
||||
@@ -67,6 +86,7 @@ describe WPScan::Model::WpVersion do
|
||||
|
||||
context 'when multiple vulns' do
|
||||
let(:number) { '3.8.1' }
|
||||
let(:db_data) { vuln_api_data_for('wordpresses/381') }
|
||||
|
||||
it 'returns the expected results' do
|
||||
@expected = [
|
||||
@@ -77,7 +97,7 @@ describe WPScan::Model::WpVersion do
|
||||
),
|
||||
WPScan::Vulnerability.new(
|
||||
'WP 3.8.1 - Vuln 2',
|
||||
{ url: %w[url-2 url-3], osvdb: %w[10], cve: %w[2014-0166], wpvulndb: '2' },
|
||||
{ url: %w[url-2 url-3], cve: %w[2014-0166], wpvulndb: '2' },
|
||||
nil,
|
||||
'3.8.2'
|
||||
)
|
||||
@@ -87,27 +107,30 @@ describe WPScan::Model::WpVersion do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#release_date' do
|
||||
describe '#metadata, #release_date, #status' do
|
||||
subject(:version) { described_class.new('3.8.1') }
|
||||
|
||||
its(:release_date) { should eql '2014-01-23' }
|
||||
before { allow(version).to receive(:db_data).and_return(db_data) }
|
||||
|
||||
context 'when the version is not in the DB' do
|
||||
subject(:version) { described_class.new('3.8.2') }
|
||||
context 'when no db_data' do
|
||||
let(:db_data) { {} }
|
||||
|
||||
its(:release_date) { should eql 'Unknown' }
|
||||
its(:release_date) { should eql '2014-01-23' }
|
||||
its(:status) { should eql 'outdated' }
|
||||
|
||||
context 'when the version is not in the metadata' do
|
||||
subject(:version) { described_class.new('3.8.2') }
|
||||
|
||||
its(:release_date) { should eql 'Unknown' }
|
||||
its(:status) { should eql 'Unknown' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#status' do
|
||||
subject(:version) { described_class.new('3.8.1') }
|
||||
context 'when db_data' do
|
||||
let(:db_data) { vuln_api_data_for('wordpresses/381') }
|
||||
|
||||
its(:status) { should eql 'outdated' }
|
||||
|
||||
context 'when the version is not in the DB' do
|
||||
subject(:version) { described_class.new('3.8.2') }
|
||||
|
||||
its(:release_date) { should eql 'Unknown' }
|
||||
its(:release_date) { should eql '2014-01-23-via-api' }
|
||||
its(:status) { should eql 'outdated-via-api' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,6 +9,7 @@ describe 'App::Views' do
|
||||
# in the expected output.
|
||||
%i[JSON CliNoColour].each do |formatter|
|
||||
context "when #{formatter}" do
|
||||
it_behaves_like 'App::Views::VulnApi'
|
||||
it_behaves_like 'App::Views::WpVersion'
|
||||
it_behaves_like 'App::Views::MainTheme'
|
||||
it_behaves_like 'App::Views::Enumeration'
|
||||
|
||||
9574
spec/fixtures/db/dynamic_finders.yml
vendored
9574
spec/fixtures/db/dynamic_finders.yml
vendored
File diff suppressed because it is too large
Load Diff
56
spec/fixtures/db/metadata.json
vendored
Normal file
56
spec/fixtures/db/metadata.json
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"wordpress": {
|
||||
"4.0": {
|
||||
"release_date": "2014-09-04",
|
||||
"status": "latest"
|
||||
},
|
||||
"3.8.1": {
|
||||
"release_date": "2014-01-23",
|
||||
"status": "outdated"
|
||||
},
|
||||
"3.8": {
|
||||
"release_date": "2013-12-12",
|
||||
"status": "insecure"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"no-vulns-popular": {
|
||||
"vulnerabilities": false,
|
||||
"popular": true,
|
||||
"latest_version": "2.0",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z"
|
||||
},
|
||||
"vulnerable-not-popular": {
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities": true
|
||||
}
|
||||
},
|
||||
"themes": {
|
||||
"no-vulns-popular": {
|
||||
"popular": true,
|
||||
"latest_version": "2.0",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z",
|
||||
"vulnerabilities": false
|
||||
},
|
||||
"vulnerable-not-popular": {
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities": true
|
||||
},
|
||||
"dignitas-themes": {
|
||||
"popular": true,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : true
|
||||
},
|
||||
"yaaburnee-themes": {
|
||||
"popular": false,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
25
spec/fixtures/db/plugins.json
vendored
25
spec/fixtures/db/plugins.json
vendored
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"no-vulns-popular": {
|
||||
"vulnerabilities": [],
|
||||
"popular": true,
|
||||
"latest_version": "2.0",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z"
|
||||
},
|
||||
"vulnerable-not-popular": {
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"title" : "First Vuln",
|
||||
"fixed_in" : "6.3.10",
|
||||
"id" : 1,
|
||||
"vuln_type": "LFI"
|
||||
},
|
||||
{
|
||||
"title": "No Fixed In",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1
spec/fixtures/db/sponsor.txt
vendored
Normal file
1
spec/fixtures/db/sponsor.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Sponsored By Kittens
|
||||
48
spec/fixtures/db/themes.json
vendored
48
spec/fixtures/db/themes.json
vendored
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"no-vulns-popular": {
|
||||
"popular": true,
|
||||
"latest_version": "2.0",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z",
|
||||
"vulnerabilities": []
|
||||
},
|
||||
"dignitas-themes": {
|
||||
"popular": true,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2015-03-05T19:25:59.000Z",
|
||||
"updated_at" : "2015-03-05T19:37:47.000Z",
|
||||
"references": {
|
||||
"url" : [
|
||||
"http://research.evex.pw/?vuln=6",
|
||||
"http://packetstormsecurity.com/files/130652/"
|
||||
]
|
||||
},
|
||||
"title" : "Dignitas 1.1.9 - Privilage Escalation",
|
||||
"id" : 7825,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
},
|
||||
"yaaburnee-themes": {
|
||||
"popular": false,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2015-03-05T19:25:44.000Z",
|
||||
"updated_at" : "2015-03-05T19:41:14.000Z",
|
||||
"references": {
|
||||
"url" : [
|
||||
"http://research.evex.pw/?vuln=6",
|
||||
"http://packetstormsecurity.com/files/130652/"
|
||||
]
|
||||
},
|
||||
"title" : "Ya'aburnee 1.0.7 - Privilage Escalation",
|
||||
"id" : 7824,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
6
spec/fixtures/db/vuln_api/plugins/no-vulns-popular.json
vendored
Normal file
6
spec/fixtures/db/vuln_api/plugins/no-vulns-popular.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"vulnerabilities": [],
|
||||
"popular": true,
|
||||
"latest_version": "2.1",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z-via-api"
|
||||
}
|
||||
17
spec/fixtures/db/vuln_api/plugins/vulnerable-not-popular.json
vendored
Normal file
17
spec/fixtures/db/vuln_api/plugins/vulnerable-not-popular.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"title" : "First Vuln \u003c= 6.3.10 - LFI",
|
||||
"fixed_in" : "6.3.10",
|
||||
"id" : 1,
|
||||
"vuln_type": "LFI"
|
||||
},
|
||||
{
|
||||
"title": "No Fixed In",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
22
spec/fixtures/db/vuln_api/themes/dignitas-themes.json
vendored
Normal file
22
spec/fixtures/db/vuln_api/themes/dignitas-themes.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"popular": true,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2015-03-05T19:25:59.000Z",
|
||||
"updated_at" : "2015-03-05T19:37:47.000Z",
|
||||
"references": {
|
||||
"url" : [
|
||||
"http://research.evex.pw/?vuln=6"
|
||||
],
|
||||
"packetstorm": [
|
||||
"130652"
|
||||
]
|
||||
},
|
||||
"title" : "Dignitas 1.1.9 - Privilage Escalation",
|
||||
"id" : 7825,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
6
spec/fixtures/db/vuln_api/themes/no-vulns-popular.json
vendored
Normal file
6
spec/fixtures/db/vuln_api/themes/no-vulns-popular.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"popular": true,
|
||||
"latest_version": "2.2",
|
||||
"last_updated": "2015-05-16T00:00:00.000Z-via-api",
|
||||
"vulnerabilities": []
|
||||
}
|
||||
17
spec/fixtures/db/vuln_api/themes/vulnerable-not-popular.json
vendored
Normal file
17
spec/fixtures/db/vuln_api/themes/vulnerable-not-popular.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"title" : "First Vuln",
|
||||
"fixed_in" : "6.3.10",
|
||||
"id" : 1,
|
||||
"vuln_type": "LFI"
|
||||
},
|
||||
{
|
||||
"title": "No Fixed In",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
22
spec/fixtures/db/vuln_api/themes/yaaburnee-themes.json
vendored
Normal file
22
spec/fixtures/db/vuln_api/themes/yaaburnee-themes.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"popular": false,
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2015-03-05T19:25:44.000Z",
|
||||
"updated_at" : "2015-03-05T19:41:14.000Z",
|
||||
"references": {
|
||||
"url" : [
|
||||
"http://research.evex.pw/?vuln=6",
|
||||
],
|
||||
"packetstorm": [
|
||||
"130652"
|
||||
]
|
||||
},
|
||||
"title" : "Ya'aburnee 1.0.7 - Privilage Escalation",
|
||||
"id" : 7824,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
17
spec/fixtures/db/vuln_api/wordpresses/38.json
vendored
Normal file
17
spec/fixtures/db/vuln_api/wordpresses/38.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"release_date" : "2013-12-12",
|
||||
"status": "insecure",
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"references": {
|
||||
"url" : ["url-4"],
|
||||
"osvdb" : ["11"]
|
||||
},
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T15:45:26.000Z",
|
||||
"title" : "WP 3.8 - Vuln 1",
|
||||
"id" : 3,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
27
spec/fixtures/db/vuln_api/wordpresses/381.json
vendored
Normal file
27
spec/fixtures/db/vuln_api/wordpresses/381.json
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"release_date" : "2014-01-23-via-api",
|
||||
"status": "outdated-via-api",
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T13:52:17.000Z",
|
||||
"title" : "WP 3.8.1 - Vuln 1",
|
||||
"id" : 1,
|
||||
"vuln_type" : "SQLI",
|
||||
"published_date" : null,
|
||||
"fixed_in" : null
|
||||
},
|
||||
{
|
||||
"references" : {
|
||||
"cve" : ["2014-0166"],
|
||||
"osvdb" : ["10"],
|
||||
"url" : ["url-2","url-3"]
|
||||
},
|
||||
"fixed_in" : "3.8.2",
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T13:53:11.000Z",
|
||||
"id" : 2,
|
||||
"title" : "WP 3.8.1 - Vuln 2"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
spec/fixtures/db/vuln_api/wordpresses/40.json
vendored
Normal file
4
spec/fixtures/db/vuln_api/wordpresses/40.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"release_date" : "2014-09-04",
|
||||
"status": "latest"
|
||||
}
|
||||
50
spec/fixtures/db/wordpresses.json
vendored
50
spec/fixtures/db/wordpresses.json
vendored
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"4.0": {
|
||||
"release_date" : "2014-09-04",
|
||||
"status": "latest"
|
||||
},
|
||||
"3.8.1": {
|
||||
"release_date" : "2014-01-23",
|
||||
"status": "outdated",
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T13:52:17.000Z",
|
||||
"title" : "WP 3.8.1 - Vuln 1",
|
||||
"id" : 1,
|
||||
"vuln_type" : "SQLI",
|
||||
"published_date" : null,
|
||||
"fixed_in" : null
|
||||
},
|
||||
{
|
||||
"references" : {
|
||||
"cve" : ["2014-0166"],
|
||||
"osvdb" : ["10"],
|
||||
"url" : ["url-2","url-3"]
|
||||
},
|
||||
"fixed_in" : "3.8.2",
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T13:53:11.000Z",
|
||||
"id" : 2,
|
||||
"title" : "WP 3.8.1 - Vuln 2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"3.8": {
|
||||
"release_date" : "2013-12-12",
|
||||
"status": "insecure",
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"references": {
|
||||
"url" : ["url-4"],
|
||||
"osvdb" : ["11"]
|
||||
},
|
||||
"created_at" : "2014-08-01T10:58:19.000Z",
|
||||
"updated_at" : "2014-09-16T15:45:26.000Z",
|
||||
"title" : "WP 3.8 - Vuln 1",
|
||||
"id" : 3,
|
||||
"vuln_type" : "AUTHBYPASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
2392
spec/fixtures/dynamic_finders/expected.yml
vendored
2392
spec/fixtures/dynamic_finders/expected.yml
vendored
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
# Copyright (C) 2019 Jörn Lund
|
||||
# This file is distributed under the same license as the ACF Dropzone plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF Dropzone 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-dropzone\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-07-04T10:29:43+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: acf-dropzone\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF Dropzone"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://github.com/mcguffin/acf-dropzone"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Drag and drop file upload for ACF-Fields."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Jörn Lund"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:47
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:47
|
||||
msgid "Enable Dropzone"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:103
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:103
|
||||
msgid "Dismiss this notice."
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:107
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:107
|
||||
msgid "Drop files here"
|
||||
msgstr ""
|
||||
|
||||
#: include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/svn/tags/1.0.0/include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/svn/trunk/include/AcfDropzone/Compat/ACF.php:108
|
||||
#: tmp/git/include/AcfDropzone/Compat/ACF.php:108
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,58 @@
|
||||
# Copyright (C) 2019 Jörn Lund
|
||||
# This file is distributed under the same license as the ACF Duplicate Repeater plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF Duplicate Repeater 2.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-duplicate-repeater\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-08-22T14:32:38+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.2.0\n"
|
||||
"X-Domain: acf-duplicate-repeater\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF Duplicate Repeater"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://github.com/mcguffin/acf-duplicate-repeater"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Duplicate Repeater and Layout Fields in ACF Pro"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Jörn Lund"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: ACF-Pro URL
|
||||
#: include/ACFDuplicateRepeater/Core/Core.php:69
|
||||
msgid "The ACF Duplicate Repeater plugin only provides support for <a href=\"%s\">ACF Pro 5.7</a> and up."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Plugins page URL
|
||||
#: include/ACFDuplicateRepeater/Core/Core.php:78
|
||||
msgid "Please upgrade ACF Pro to the latest Version on the <a href=\"%s\">plugins page</a>."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Plugins page URL
|
||||
#: include/ACFDuplicateRepeater/Core/Core.php:87
|
||||
msgid "You can disable and uninstall the plugin on the <a href=\"%2$s\">plugins page</a>."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFDuplicateRepeater/Core/Core.php:123
|
||||
msgid "Duplicate Entry"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFDuplicateRepeater/Core/Core.php:127
|
||||
msgid "Duplicate Layout"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,4 @@
|
||||
# Changelog ##
|
||||
|
||||
## 1.0.0 - 26 Aug 2019
|
||||
* Initial release
|
||||
@@ -0,0 +1,4 @@
|
||||
# Changelog ##
|
||||
|
||||
## 1.0.0 - 16 Aug 2019
|
||||
* Initial release
|
||||
@@ -0,0 +1,225 @@
|
||||
# Copyright (C) 2019 Jörn Lund
|
||||
# This file is distributed under the same license as the ACF OpenStreetMap Field plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF OpenStreetMap Field 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-field-openstreetmap\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-07-05T08:37:19+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.1.0\n"
|
||||
"X-Domain: acf-openstreetmap-field\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF OpenStreetMap Field"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://wordpress.org/plugins/acf-openstreetmap-field"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "A configurable OpenStreetMap Field for ACF."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Jörn Lund"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
msgid "OpenStreetMap Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:37
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:51
|
||||
msgid "OpenStreetMap"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:51
|
||||
msgid "acf-openstreetmap-field Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:57
|
||||
msgid "Save Settings"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:86
|
||||
msgid "Access Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Settings/SettingsOpenStreetMap.php:139
|
||||
msgid "Enter Access Tokens for various Map Tile providers."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:125
|
||||
msgid "Raw Data"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:126
|
||||
msgid "Leaflet JS"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:127
|
||||
msgid "iFrame (OpenStreetMap.org)"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:146
|
||||
msgid "Map Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:147
|
||||
msgid "Set zoom, center and select layers being displayed."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:167
|
||||
msgid "Map Position"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:168
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:179
|
||||
msgid "Center the initial map"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:171
|
||||
msgid "lat"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:178
|
||||
msgid "Center"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:182
|
||||
msgid "lng"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:190
|
||||
msgid "Zoom"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:191
|
||||
msgid "Set the initial zoom level"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:196
|
||||
msgid "zoom"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:203
|
||||
msgid "Allow layer selection"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:213
|
||||
msgid "Customise the map height"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:222
|
||||
msgid "Max. number of Markers"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:223
|
||||
msgid "Leave empty for infinite markers"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:380
|
||||
msgid "Locate Marker"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:407
|
||||
msgid "Remove Marker"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/svn/tags/1.0.0/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/svn/trunk/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
#: tmp/git/include/ACFFieldOpenstreetmap/Field/OpenStreetMap.php:734
|
||||
msgid "View Larger Map"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,153 @@
|
||||
# Copyright (C) 2019 mcguffin
|
||||
# This file is distributed under the same license as the ACF QuickEdit Fields plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: ACF QuickEdit Fields 3.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/acf-quick-edit-fields\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-09-03T06:48:12+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.2.0\n"
|
||||
"X-Domain: acf-quickedit-fields\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "ACF QuickEdit Fields"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://github.com/mcguffin/acf-quickedit-fields"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Show Advanced Custom Fields in post list table. Edit field values in Quick Edit and / or Bulk edit."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://github.com/mcguffin"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:52
|
||||
msgid "Column View"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:56
|
||||
msgid "Show a column in the posts list table"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:78
|
||||
msgid "Show Column"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:83
|
||||
msgid "Show column in list tables"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:91
|
||||
msgid "Sortable Column"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:96
|
||||
msgid "Make this column sortable"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:106
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:110
|
||||
msgid "Column Weight"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:107
|
||||
msgid "Columns with a higher weight will be pushed to the right. The leftmost WordPress column has a weight of <em>0</em>, the next one <em>100</em> and so on. Leave empty to place a column to the rightmost position."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:144
|
||||
msgid "Editing"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:169
|
||||
msgid "QuickEdit"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:174
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:191
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:175
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:192
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Admin/FieldGroup.php:186
|
||||
msgid "Bulk Edit"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 1: ACF Pro URL, 2: plugins page url
|
||||
#: include/ACFQuickEdit/Admin/Admin.php:178
|
||||
msgid "The <strong>ACF QuickEdit Fields</strong> plugin requires <a href=\"%1$s\">ACF version 5.6 or later</a>. You can disable and uninstall it on the <a href=\"%2$s\">plugins page</a>."
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/LinkField.php:58
|
||||
msgid "Select Link"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/LinkField.php:59
|
||||
msgid "Remove Link"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/PasswordField.php:22
|
||||
#: include/ACFQuickEdit/Fields/NumberField.php:24
|
||||
#: include/ACFQuickEdit/Fields/ChoiceField.php:57
|
||||
#: include/ACFQuickEdit/Fields/TaxonomyField.php:42
|
||||
#: include/ACFQuickEdit/Fields/PageLinkField.php:22
|
||||
#: include/ACFQuickEdit/Fields/DateTimePickerField.php:18
|
||||
msgid "(No value)"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/FileField.php:46
|
||||
msgid "Select File"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/FileField.php:47
|
||||
msgid "Remove File"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/TaxonomyField.php:98
|
||||
#: include/ACFQuickEdit/Fields/TaxonomyField.php:114
|
||||
msgid "– No Selection –"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/Field.php:267
|
||||
msgid "Do not change"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/RelationshipField.php:73
|
||||
msgid "Private"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/PostObjectField.php:55
|
||||
msgid "(no title)"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/CheckboxField.php:57
|
||||
msgid "Add Choice"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Fields/SelectField.php:31
|
||||
msgid "— Select —"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Ajax/AjaxHandler.php:156
|
||||
msgid "Nonce invalid"
|
||||
msgstr ""
|
||||
|
||||
#: include/ACFQuickEdit/Ajax/AjaxHandler.php:161
|
||||
msgid "Insufficient Permission"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,238 @@
|
||||
# Copyright (C) 2019 Palbo Capello
|
||||
# This file is distributed under the GPL-2.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Advanced Custom Types for Divi 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/advanced-custom-types-divi\n"
|
||||
"POT-Creation-Date: 2019-06-29 00:00:14+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: en\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Country: United States\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
|
||||
"attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
|
||||
"X-Poedit-Basepath: ../\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-Bookmarks: \n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
"X-Generator: grunt-wp-i18n1.0.2\n"
|
||||
|
||||
#: advanced-custom-types-divi.php:32
|
||||
msgid ""
|
||||
"Advanced Custom Types for Divi was deactivated because <span "
|
||||
"style='font-weight: bold;'>ACT for Divi PRO</span> is active"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-act-divi.php:266
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-act-divi.php:267
|
||||
msgid "License"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:15
|
||||
msgid "ACT Post Type Grid"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:81
|
||||
msgid "View more button"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:116
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:124
|
||||
msgid "Body"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:127
|
||||
msgid "Button"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:153
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:157
|
||||
msgid "Query"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:165
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:339
|
||||
msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:169
|
||||
msgid "Card"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:182
|
||||
msgid "Show title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:185
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:201
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:233
|
||||
msgid "Toggle whether mushroom will be added to the pizza."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:189
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:205
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:237
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:396
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:190
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:206
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:238
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:397
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:198
|
||||
msgid "Show thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:213
|
||||
msgid "Thumbnail size"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:218
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:250
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:269
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:343
|
||||
msgid "Content entered here will appear inside the module."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:230
|
||||
msgid "Show content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:245
|
||||
msgid "Content length"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:265
|
||||
msgid "Post type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:276
|
||||
msgid "Posts limit"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:279
|
||||
msgid "Posts limit."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:286
|
||||
msgid "Posts offset"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:289
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:301
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:313
|
||||
msgid "Posts offset."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:296
|
||||
msgid "Order"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:308
|
||||
msgid "Order by"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:323
|
||||
msgid "View more text"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:326
|
||||
msgid "Post button."
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:352
|
||||
msgid "Heading Level"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:356
|
||||
msgid "H1"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:357
|
||||
msgid "H2"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:358
|
||||
msgid "H3"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:359
|
||||
msgid "H4"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:360
|
||||
msgid "H5"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:361
|
||||
msgid "H6"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:371
|
||||
msgid "Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:375
|
||||
msgid "1 Column"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:376
|
||||
msgid "2 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:377
|
||||
msgid "3 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:378
|
||||
msgid "4 Columns"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:389
|
||||
msgid "Card inner padding"
|
||||
msgstr ""
|
||||
|
||||
#: includes/modules/ACTPostTypeGrid/ACTPostTypeGrid.php:392
|
||||
msgid "Card inner padding."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Advanced Custom Types for Divi"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://www.advancedcustomtypes.io"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "Advanced custom types for Divi theme and Divi builder."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Palbo Capello"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "http://capellopablo.com/"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,231 @@
|
||||
# Copyright (C) 2019 Idenovasi
|
||||
# This file is distributed under the same license as the Advanced Random Posts Widget package.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Advanced Random Posts Widget 2.2.0\n"
|
||||
"Report-Msgid-Bugs-To: https://idenovasi.com/contact/\n"
|
||||
"POT-Creation-Date: 2019-03-07 16:09:37+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Idenovasi\n"
|
||||
"Language-Team: Idenovasi\n"
|
||||
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-Language: English\n"
|
||||
"X-Poedit-Country: UNITED STATES\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-KeywordsList: "
|
||||
"__;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c;_nc:4c,1,2;_"
|
||||
"x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
|
||||
"X-Textdomain-Support: yes\n"
|
||||
|
||||
#: includes/form.php:48
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:55
|
||||
msgid "Title URL"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:62
|
||||
msgid "CSS Class"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:69
|
||||
msgid "HTML or text before the random posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:76
|
||||
msgid "HTML or text after the random posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:88
|
||||
msgid "Ignore sticky posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:94
|
||||
msgid "Number of posts to show"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:97
|
||||
msgid "to show all posts."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:102
|
||||
msgid "Offset"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:105
|
||||
msgid "The number of posts to skip"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:110
|
||||
msgid "Post type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:121
|
||||
msgid "Post status"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:136
|
||||
msgid "Limit to Category"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:152
|
||||
msgid "Limit to Tag"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:168
|
||||
msgid "Limit to Taxonomy"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:171
|
||||
msgid "Ex: category=1,2,4&post_tag=6,12"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:172
|
||||
msgid "Available: "
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:184
|
||||
msgid "Display thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:190
|
||||
msgid "Thumbnail Size "
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:197
|
||||
msgid "Please read %1$sFAQ%2$s for more information."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:203
|
||||
msgid "Use custom thumbnail sizes"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:209
|
||||
msgid "Width & Height"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:217
|
||||
msgid "Thumbnail Alignment"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:220
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:221
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:222
|
||||
msgid "Center"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:227
|
||||
msgid ""
|
||||
"Your theme does not support Post Thumbnail feature, please go to "
|
||||
"%1$shttp://codex.wordpress.org/Post_Thumbnails%2$s to read more info and "
|
||||
"how to activate it in your theme."
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:237
|
||||
msgid "Display full post"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:244
|
||||
msgid "Display excerpt"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:250
|
||||
msgid "Excerpt Length"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:258
|
||||
msgid "Display Date"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:265
|
||||
msgid "Display Modified Date"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:272
|
||||
msgid "Use Relative Date. eg: 5 days ago"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:282
|
||||
msgid "Custom CSS"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:285
|
||||
msgid "You can find the plugin css selector on %1$sFAQ page%2$s."
|
||||
msgstr ""
|
||||
|
||||
#: includes/functions.php:14 includes/widget.php:27
|
||||
msgid "Random Posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/posts.php:101 includes/posts.php:107
|
||||
msgid "%s ago"
|
||||
msgstr ""
|
||||
|
||||
#: includes/widget.php:17
|
||||
msgid ""
|
||||
"An advanced widget that gives you total control over the output of the "
|
||||
"random posts."
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "Advanced Random Posts Widget"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin/theme
|
||||
msgid "https://github.com/idenovasi/advanced-random-posts-widget"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid "Easily to display advanced random posts via shortcode or widget."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "Idenovasi"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "https://idenovasi.com/"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:34
|
||||
msgctxt "widget tab name"
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:35
|
||||
msgctxt "widget tab name"
|
||||
msgid "Posts"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:36
|
||||
msgctxt "widget tab name"
|
||||
msgid "Taxonomy"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:37
|
||||
msgctxt "widget tab name"
|
||||
msgid "Thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:38
|
||||
msgctxt "widget tab name"
|
||||
msgid "Extras"
|
||||
msgstr ""
|
||||
|
||||
#: includes/form.php:39
|
||||
msgctxt "widget tab name"
|
||||
msgid "Custom CSS"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,171 @@
|
||||
# Copyright (C) 2019 SuitePlugins
|
||||
# This file is distributed under the GPLv2 or later (license.txt).
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SuitePlugins - Advanced XProfile Fields for BuddyPress "
|
||||
"1.0.4\n"
|
||||
"Report-Msgid-Bugs-To: "
|
||||
"https://wordpress.org/support/plugin/advanced-xprofile-fields-for-"
|
||||
"buddypress\n"
|
||||
"POT-Creation-Date: 2019-09-08 03:48:34+00:00\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"X-Generator: grunt-wp-i18n 1.0.3\n"
|
||||
|
||||
#: admin/template/metabox.php:31
|
||||
msgid "Labels"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/metabox.php:32
|
||||
msgid "Validation"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/metabox.php:34
|
||||
msgid "Advanced Options"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:6
|
||||
msgid "Hide on registration"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:9
|
||||
msgid "Hide field on registration page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:15
|
||||
msgid "Non editable"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:18
|
||||
msgid "Stop profile field from being updated"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:24
|
||||
msgid "Show in Admin Column"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-advanced.php:27
|
||||
msgid "Display a column on admin user listing page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:6
|
||||
msgid "Registration"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:12
|
||||
msgid "Label on registration page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:19
|
||||
msgid "Self Profile"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:25
|
||||
msgid "Label while viewing your profile"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:32
|
||||
msgid "User's Profile"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:38
|
||||
msgid "Label while viewing another member's page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:45
|
||||
msgid "Edit Profile"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:51
|
||||
msgid "Label on edit profile page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:58
|
||||
msgid "Admin Column"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-labels.php:64
|
||||
msgid "Admin column title "
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:5
|
||||
msgid "Character Limit"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:9
|
||||
msgid "Set the maximum amount of characters for this field."
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:15
|
||||
msgid "Minimum Characters"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:19
|
||||
msgid "Set the minimum amount of characters for this field."
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:25
|
||||
msgid "Text Format"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:28
|
||||
msgid "-Select Format-"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:30
|
||||
msgid "Alphanumeric"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:33
|
||||
msgid "Alpha"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:36
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:39
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
#: admin/template/tab-validation.php:43
|
||||
msgid "Choose the text format for an input field."
|
||||
msgstr ""
|
||||
|
||||
#: sp-advanced-xprofile.php:242
|
||||
msgid "Please enter only letters"
|
||||
msgstr ""
|
||||
|
||||
#: sp-advanced-xprofile.php:246
|
||||
msgid "Letters, numbers, and underscores only"
|
||||
msgstr ""
|
||||
|
||||
#: sp-advanced-xprofile.php:268
|
||||
msgid "Please specify a valid state"
|
||||
msgstr ""
|
||||
|
||||
#: sp-advanced-xprofile.php:272
|
||||
msgid "The specified US ZIP Code is invalid"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin Name of the plugin/theme
|
||||
msgid "SuitePlugins - Advanced XProfile Fields for BuddyPress"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin/theme
|
||||
msgid "http://suiteplugins.com"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin/theme
|
||||
msgid ""
|
||||
"Enhance your BuddyPress profile fields with Advanced XProfile Fields for "
|
||||
"BuddyPress. Manage fields labels, validation and show fields in admin."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin/theme
|
||||
msgid "SuitePlugins"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,593 @@
|
||||
# Copyright (C) 2019 Arya Themes
|
||||
# This file is distributed under the same license as the Arya License Manager plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Arya License Manager 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/arya-license-manager\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-08-27T01:28:03+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.3.0\n"
|
||||
"X-Domain: arya-license-manager\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Arya License Manager"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://gitlab.com/arya-license-manager"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Arya License Manager integrates with WooCommerce to simplify the creation and management of software licenses."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Arya Themes"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://www.aryathemes.com"
|
||||
msgstr ""
|
||||
|
||||
#: compatibility.php:33
|
||||
msgid "Arya License Manager requires WooCommerce 3.6.0 or greater."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Admin.php:95
|
||||
msgid "Licenses Management"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Admin.php:96
|
||||
#: src/Admin/Settings.php:61
|
||||
#: src/Admin/Settings.php:83
|
||||
#: src/Admin/Settings.php:181
|
||||
#: src/Storefront/Account.php:81
|
||||
#: src/Storefront/Query.php:69
|
||||
#: templates/emails/email-licenses.php:8
|
||||
#: templates/emails/plain/email-licenses.php:10
|
||||
#: templates/myaccount/order-licenses.php:8
|
||||
msgid "Licenses"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:48
|
||||
#: src/Admin/License.php:187
|
||||
#: src/Admin/Product/Simple.php:63
|
||||
#: src/Admin/Product/Simple.php:64
|
||||
#: src/Admin/Product/Variable.php:65
|
||||
#: src/Storefront/Licenses.php:73
|
||||
#: src/Storefront/Licenses.php:102
|
||||
#: src/Storefront/Licenses.php:113
|
||||
#: src/Storefront/Order.php:292
|
||||
#: src/Storefront/Query.php:72
|
||||
#: templates/emails/email-licenses.php:17
|
||||
#: templates/myaccount/order-licenses.php:15
|
||||
#: templates/myaccount/order-licenses.php:43
|
||||
msgid "License"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:49
|
||||
#: src/Storefront/Order.php:304
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:50
|
||||
#: src/Storefront/License.php:107
|
||||
#: templates/emails/email-licenses.php:16
|
||||
#: templates/myaccount/order-licenses.php:14
|
||||
#: templates/myaccount/order-licenses.php:42
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:51
|
||||
#: src/Admin/License.php:130
|
||||
#: templates/myaccount/license.php:26
|
||||
msgid "Activations"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:52
|
||||
#: src/Admin/License.php:191
|
||||
#: src/Storefront/Order.php:295
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:53
|
||||
#: src/Admin/License.php:203
|
||||
#: src/Storefront/License.php:111
|
||||
msgid "Service start date"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:54
|
||||
#: src/Admin/License.php:207
|
||||
#: src/Storefront/License.php:115
|
||||
msgid "Service end date"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:55
|
||||
msgid "Order"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:155
|
||||
msgid "No licenses found."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:226
|
||||
#: src/Storefront/License.php:103
|
||||
msgid "unlimited"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s of %s: number of activations
|
||||
#: src/Admin/Analytics/Licenses.php:229
|
||||
#: src/Storefront/License.php:103
|
||||
msgid "%1$s of %2$s"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s ago: human-readable time
|
||||
#: src/Admin/Analytics/Licenses.php:264
|
||||
msgctxt "%s = human-readable time"
|
||||
msgid "%s ago"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Analytics/Licenses.php:303
|
||||
msgid "Regenerate download permissions"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:24
|
||||
msgid "Expired license"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:25
|
||||
msgid "Expired license emails are sent when a license has been deactivated by manager."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:54
|
||||
msgid "[{site_title}]: License {license} has expired"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:64
|
||||
msgid "Expired license: <code>{license}</code>"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:120
|
||||
#: src/Admin/Emails/Suspended.php:124
|
||||
msgid "Enable/Disable"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:122
|
||||
#: src/Admin/Emails/Suspended.php:126
|
||||
msgid "Enable this email notification"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:126
|
||||
#: src/Admin/Emails/Suspended.php:130
|
||||
msgid "Recipient(s)"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Defaults to %s: Recipients for this email
|
||||
#: src/Admin/Emails/Expired.php:128
|
||||
#: src/Admin/Emails/Suspended.php:132
|
||||
msgid "Enter recipients (comma separated) for this email. Defaults to %s."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:134
|
||||
#: src/Admin/Emails/Suspended.php:138
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Available placeholders: %s: Available placeholders
|
||||
#: src/Admin/Emails/Expired.php:136
|
||||
#: src/Admin/Emails/Expired.php:145
|
||||
#: src/Admin/Emails/Suspended.php:140
|
||||
#: src/Admin/Emails/Suspended.php:149
|
||||
msgid "Available placeholders: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:142
|
||||
#: src/Admin/Emails/Suspended.php:146
|
||||
msgid "Email heading"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:150
|
||||
#: src/Admin/Emails/Suspended.php:154
|
||||
msgid "Email type"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Expired.php:152
|
||||
#: src/Admin/Emails/Suspended.php:156
|
||||
msgid "Choose which format of email to send."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Suspended.php:24
|
||||
msgid "Suspended license"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Suspended.php:25
|
||||
msgid "Suspended license emails are sent when a license has been deactivated by manager."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Suspended.php:54
|
||||
msgid "[{site_title}]: License {license} has been suspended"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Emails/Suspended.php:64
|
||||
msgid "License suspended: {license}"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Integration.php:80
|
||||
#: src/Admin/Integration.php:101
|
||||
msgctxt "WooCommerce header breadcrumbs"
|
||||
msgid "Licenses"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Integration.php:89
|
||||
msgctxt "WooCommerce header breadcrumbs"
|
||||
msgid "License details"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:83
|
||||
#: templates/myaccount/license.php:14
|
||||
msgid "License not available."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:89
|
||||
msgid "License details"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:128
|
||||
msgid "Information"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:133
|
||||
#: src/Admin/License.php:243
|
||||
#: src/Storefront/License.php:145
|
||||
#: src/Storefront/Licenses.php:74
|
||||
#: src/Storefront/Licenses.php:103
|
||||
#: src/Storefront/Licenses.php:114
|
||||
#: templates/myaccount/order-licenses.php:16
|
||||
#: templates/myaccount/order-licenses.php:44
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:147
|
||||
#: src/Storefront/Cart.php:116
|
||||
#: src/Storefront/Order.php:332
|
||||
msgid "Unlimited activations"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %d activation: number of activations
|
||||
#: src/Admin/License.php:149
|
||||
#: src/Storefront/Cart.php:118
|
||||
#: src/Storefront/Order.php:334
|
||||
msgid "%d activation"
|
||||
msgid_plural "%d activations"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Admin/License.php:195
|
||||
#: src/Admin/Product.php:121
|
||||
#: src/Admin/Product/Variable.php:121
|
||||
#: src/Storefront/License.php:119
|
||||
msgid "License type"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:199
|
||||
msgid "Product HM"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:211
|
||||
#: src/Storefront/License.php:123
|
||||
msgid "Allowed activations"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:215
|
||||
msgid "Order / Customer"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:241
|
||||
#: src/Storefront/License.php:143
|
||||
msgid "Activation"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:242
|
||||
#: src/Storefront/License.php:144
|
||||
#: src/Storefront/Order.php:307
|
||||
msgid "Activation date"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:258
|
||||
#: src/Storefront/License.php:206
|
||||
msgid "Associate"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:262
|
||||
#: src/License/Traits/LicenseTrait.php:98
|
||||
#: src/Storefront/License.php:208
|
||||
msgid "WordPress"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:263
|
||||
#: src/License/Traits/LicenseTrait.php:101
|
||||
#: src/Storefront/License.php:209
|
||||
msgid "Web Application"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:271
|
||||
#: src/Storefront/License.php:214
|
||||
msgid "Website URL"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:278
|
||||
#: src/Storefront/License.php:217
|
||||
msgid "The IP address of the provided website is automatically assigned."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:286
|
||||
msgid "Associate license"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:307
|
||||
#: src/Storefront/License.php:154
|
||||
msgid "This license has not been associated to a website."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:325
|
||||
#: src/Storefront/License.php:172
|
||||
msgid "Revoke"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:352
|
||||
msgid "Activate"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:353
|
||||
msgid "Deactivate"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:354
|
||||
msgid "Renew"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:361
|
||||
msgid "Choose an action..."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:369
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/License.php:389
|
||||
#: src/Storefront/Account.php:217
|
||||
msgid "It was not possible to associate the license."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Licenses.php:61
|
||||
msgid "License Management"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Licenses.php:86
|
||||
msgid "Number of licenses per page:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Order.php:60
|
||||
#: src/Storefront/Order.php:113
|
||||
msgid "Regenerate download permissions for licenses"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:70
|
||||
msgid "Software License"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:99
|
||||
#: src/Admin/Product/Variable.php:90
|
||||
msgid "Expiry time"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:110
|
||||
#: src/Admin/Product/Variable.php:97
|
||||
msgid "Expire interval"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:113
|
||||
#: src/Admin/Product/Variable.php:100
|
||||
msgid "Years"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:114
|
||||
#: src/Admin/Product/Variable.php:101
|
||||
msgid "Months"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:115
|
||||
#: src/Admin/Product/Variable.php:102
|
||||
msgid "Days"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:124
|
||||
#: src/Admin/Product/Variable.php:124
|
||||
msgid "On-demand software"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:125
|
||||
#: src/Admin/Product/Variable.php:125
|
||||
#: src/License/Traits/LicenseTrait.php:48
|
||||
msgid "Perpetual"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:135
|
||||
#: src/Admin/Product/Variable.php:109
|
||||
#: src/Storefront/Cart.php:93
|
||||
msgid "Activation limit"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:136
|
||||
#: src/Admin/Product/Variable.php:111
|
||||
msgid "Leave blank for unlimited activations."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product.php:139
|
||||
#: src/Admin/Product/Variable.php:114
|
||||
msgid "Unlimited"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product/License.php:63
|
||||
msgid "Software license"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Product/Variable.php:64
|
||||
msgid "Enable this option if the product is associated to a license."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Request.php:82
|
||||
#: src/Admin/Request.php:132
|
||||
#: src/Admin/Request.php:178
|
||||
msgid "It is not possible to perform an action since the order has not been completed."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:84
|
||||
msgid "The following options are used to configure licenses format."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:89
|
||||
msgid "Length"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:90
|
||||
msgid "Number of characters to generate a new license. Licenses shall have a minimum length of 10 characters."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:102
|
||||
msgid "Chunks"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:103
|
||||
msgid "Split a license into chunks."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:115
|
||||
msgid "Prefix"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:116
|
||||
msgid "Add the prefix to the generated license."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:124
|
||||
msgid "Suffix"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:125
|
||||
msgid "Add the suffix to the generated license."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:142
|
||||
msgid "Account page"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:147
|
||||
msgid "Pagination"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:148
|
||||
msgid "Limits the number of licenses to display on \"My Account\" page."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:182
|
||||
msgid "Endpoint for the \"Licenses\" page."
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:189
|
||||
msgid "View license"
|
||||
msgstr ""
|
||||
|
||||
#: src/Admin/Settings.php:190
|
||||
msgid "Endpoint for the \"View license\" page."
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:51
|
||||
msgid "On demand software"
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:68
|
||||
msgid "Valid"
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:69
|
||||
msgid "Expired"
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:70
|
||||
msgid "Suspended"
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:71
|
||||
msgid "Inactive"
|
||||
msgstr ""
|
||||
|
||||
#: src/License/Traits/LicenseTrait.php:84
|
||||
#: src/Storefront/Cart.php:120
|
||||
msgid "Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Account.php:96
|
||||
msgid "You do not have permission to view the license information."
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Cart.php:99
|
||||
#: src/Storefront/Order.php:298
|
||||
msgid "Activation period"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/License.php:224
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Licenses.php:72
|
||||
#: src/Storefront/Licenses.php:101
|
||||
#: src/Storefront/Licenses.php:112
|
||||
msgid "Software"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Licenses.php:96
|
||||
#: templates/myaccount/order-licenses.php:37
|
||||
msgid "Manage"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Licenses.php:145
|
||||
msgid "«"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Licenses.php:146
|
||||
msgid "»"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Order.php:301
|
||||
msgid "Activations limit"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Order.php:310
|
||||
msgid "Expiry date"
|
||||
msgstr ""
|
||||
|
||||
#: src/Storefront/Product.php:79
|
||||
msgid "Add to cart"
|
||||
msgstr ""
|
||||
|
||||
#: templates/myaccount/license.php:10
|
||||
msgid "Invalid license."
|
||||
msgstr ""
|
||||
|
||||
#: templates/myaccount/license.php:22
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
#: templates/myaccount/licenses.php:12
|
||||
msgid "Go shop"
|
||||
msgstr ""
|
||||
|
||||
#: templates/myaccount/licenses.php:14
|
||||
msgid "There are no active licenses."
|
||||
msgstr ""
|
||||
336
spec/fixtures/dynamic_finders/plugin_version/asmember/translation_file/languages/asmember-de_DE.po
vendored
Normal file
336
spec/fixtures/dynamic_finders/plugin_version/asmember/translation_file/languages/asmember-de_DE.po
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: asMember 1.0\n"
|
||||
"POT-Creation-Date: 2019-06-25 12:18+0200\n"
|
||||
"PO-Revision-Date: 2019-06-25 12:46+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-KeywordsList: __\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: admin/admin.php:62
|
||||
msgid "Visibility"
|
||||
msgstr ""
|
||||
|
||||
#: admin/admin.php:64
|
||||
msgid "public"
|
||||
msgstr ""
|
||||
|
||||
#: admin/admin.php:65
|
||||
msgid "Only Members"
|
||||
msgstr "Nur für Mitglieder"
|
||||
|
||||
#: admin/admin.php:95
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
|
||||
#: admin/admin.php:111 admin/admin.php:112
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#: admin/options.php:143
|
||||
msgid "Seite wählen"
|
||||
msgstr ""
|
||||
|
||||
#: public/members.php:119 public/user-account.php:226
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: public/members.php:126 public/members.php:248
|
||||
msgid "Interests"
|
||||
msgstr "Interessen"
|
||||
|
||||
#: public/members.php:133
|
||||
msgid "Ads"
|
||||
msgstr ""
|
||||
|
||||
#: public/members.php:153 public/user-account.php:194
|
||||
#: public/user-account.php:319
|
||||
msgid "About me"
|
||||
msgstr "Über mich"
|
||||
|
||||
#: public/members.php:163
|
||||
msgid "Contact"
|
||||
msgstr "Kontakt"
|
||||
|
||||
#: public/members.php:198 public/user-account.php:377
|
||||
msgid "I search"
|
||||
msgstr "Ich suche"
|
||||
|
||||
#: public/members.php:208 public/user-account.php:372
|
||||
msgid "I offer"
|
||||
msgstr "Ich biete"
|
||||
|
||||
#: public/members.php:256 public/user-account.php:335
|
||||
msgid "favorite quote"
|
||||
msgstr ""
|
||||
|
||||
#: public/members.php:270 public/user-account.php:345
|
||||
msgid "favorite music"
|
||||
msgstr ""
|
||||
|
||||
#: public/members.php:280 public/user-account.php:355
|
||||
msgid "favorite film"
|
||||
msgstr "Lieblingsfilm"
|
||||
|
||||
#: public/members.php:291 public/user-account.php:350
|
||||
msgid "favorite book"
|
||||
msgstr "Lieblingsbuch"
|
||||
|
||||
#: public/user-account.php:131 public/user-account.php:256
|
||||
msgid "Address"
|
||||
msgstr "Anrede"
|
||||
|
||||
#: public/user-account.php:133 public/user-account.php:258
|
||||
#: public/user-register.php:604
|
||||
msgid "Sir"
|
||||
msgstr "Herr"
|
||||
|
||||
#: public/user-account.php:134 public/user-account.php:259
|
||||
#: public/user-register.php:603
|
||||
msgid "Madame"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:139 public/user-account.php:140
|
||||
#: public/user-account.php:264 public/user-account.php:265
|
||||
#: public/user-register.php:609
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:144 public/user-account.php:145
|
||||
#: public/user-account.php:269 public/user-account.php:270
|
||||
#: public/user-register.php:615
|
||||
msgid "Firstname"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:150 public/user-account.php:151
|
||||
#: public/user-account.php:275 public/user-account.php:276
|
||||
#: public/user-register.php:621
|
||||
msgid "Lastname"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:162 public/user-account.php:163
|
||||
#: public/user-account.php:287 public/user-account.php:288
|
||||
#: public/user-register.php:631
|
||||
msgid "Street"
|
||||
msgstr "Straße"
|
||||
|
||||
#: public/user-account.php:168 public/user-account.php:169
|
||||
#: public/user-account.php:293 public/user-account.php:294
|
||||
#: public/user-register.php:636
|
||||
msgid "Zipcode"
|
||||
msgstr "PLZ"
|
||||
|
||||
#: public/user-account.php:174 public/user-account.php:175
|
||||
#: public/user-account.php:299 public/user-account.php:300
|
||||
#: public/user-register.php:642
|
||||
msgid "City"
|
||||
msgstr "Ort"
|
||||
|
||||
#: public/user-account.php:182 public/user-account.php:307
|
||||
msgid "Birthday"
|
||||
msgstr "Geburtstag"
|
||||
|
||||
#: public/user-account.php:208 public/user-account.php:422
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: public/user-account.php:231
|
||||
msgid "Detail"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:235
|
||||
msgid "Offer/Search"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:239 public/user-account.php:394
|
||||
msgid "Avatar"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:340
|
||||
msgid "interests"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-account.php:400 public/user-account.php:404
|
||||
msgid "Upload Avatar"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-dashboard.php:24
|
||||
msgid "Welcome"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-dashboard.php:33
|
||||
msgid "not logged in"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:32
|
||||
msgid "Benutzer/Email"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:33
|
||||
msgid "Passwort"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:34
|
||||
msgid "Eingeloggt bleiben"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:35 public/user-login.php:61
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:47 public/user-login.php:48
|
||||
msgid "Username oder Email"
|
||||
msgstr "Benutzer oder EMail"
|
||||
|
||||
#: public/user-login.php:51 public/user-login.php:52
|
||||
#: public/user-register.php:117 public/user-register.php:684
|
||||
#: public/user-register.php:685
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: public/user-login.php:56
|
||||
msgid "Be Logged in"
|
||||
msgstr "Sie sind eingeloggt"
|
||||
|
||||
#: public/user-login.php:74
|
||||
msgid "Reset password"
|
||||
msgstr "Passwort vergessen"
|
||||
|
||||
#: public/user-login.php:80 public/user-register.php:128
|
||||
#: public/user-register.php:742
|
||||
msgid "Register"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-login.php:121
|
||||
msgid "<strong>ERROR</strong>: Invalid username or incorrect password."
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:27
|
||||
msgid "You are logged in"
|
||||
msgstr "Sie sind bereits eingeloggt."
|
||||
|
||||
#: public/user-register.php:27
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:34
|
||||
msgid "Register disabled"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:56
|
||||
msgid "Your membership has been successfully activated"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:59 public/user-register.php:106
|
||||
#: public/user-register.php:186
|
||||
msgid "Activation was not successful"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:116
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:127
|
||||
msgid "Lost password"
|
||||
msgstr "Passwort vergessen"
|
||||
|
||||
#: public/user-register.php:174
|
||||
msgid "A membership application for this email has already been created."
|
||||
msgstr "Ein Mitgliedsantrag zu dieser Email wurde bereits angelegt."
|
||||
|
||||
#: public/user-register.php:294 public/user-register.php:515
|
||||
msgid "Please enter a valid email address!"
|
||||
msgstr "Bitte geben Sie eine gültige EMail ein!"
|
||||
|
||||
#: public/user-register.php:405
|
||||
msgid ""
|
||||
"Your account has been successfully created. You will receive an email with a "
|
||||
"confirmation link to activate your account."
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:437 public/user-register.php:449
|
||||
#: public/user-register.php:461 public/user-register.php:471
|
||||
#: public/user-register.php:481 public/user-register.php:491
|
||||
#: public/user-register.php:507
|
||||
msgid "Please fill in this field!"
|
||||
msgstr "Bitte füllen Sie dieses Feld aus!"
|
||||
|
||||
#: public/user-register.php:529 public/user-register.php:538
|
||||
msgid "Please enter a password with at least 8 characters!"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:547
|
||||
msgid "The passwords must be identical."
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:557
|
||||
msgid "Please confirm the terms and conditions."
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:566
|
||||
msgid "Please confirm the privacy policy"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:601
|
||||
msgid "address"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:616
|
||||
msgid "Your firstname"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:622
|
||||
msgid "Your lastname"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:632
|
||||
msgid "Your street"
|
||||
msgstr "Ihre Straße"
|
||||
|
||||
#: public/user-register.php:637
|
||||
msgid "Your zipcode"
|
||||
msgstr "Ihre PLZ"
|
||||
|
||||
#: public/user-register.php:643
|
||||
msgid "Your City"
|
||||
msgstr ""
|
||||
|
||||
#: public/user-register.php:647
|
||||
msgid "Phone"
|
||||
msgstr "Telefon"
|
||||
|
||||
#: public/user-register.php:648
|
||||
msgid "Your phone"
|
||||
msgstr "Ihre Telefonnummer"
|
||||
|
||||
#: public/user-register.php:670
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: public/user-register.php:671
|
||||
msgid "Your name"
|
||||
msgstr "Ihr Name"
|
||||
|
||||
#: public/user-register.php:679
|
||||
msgid "EMail"
|
||||
msgstr "EMail"
|
||||
|
||||
#: public/user-register.php:680
|
||||
msgid "Your Email"
|
||||
msgstr "Ihre Email"
|
||||
|
||||
#: public/user-register.php:689 public/user-register.php:690
|
||||
msgid "Repeat password"
|
||||
msgstr "Passwort wiederholen"
|
||||
|
||||
#: public/user-register.php:704
|
||||
msgid "Membership"
|
||||
msgstr "Mitgliedschaft"
|
||||
9
spec/fixtures/dynamic_finders/plugin_version/astra-widgets/change_log/changelog.txt
vendored
Normal file
9
spec/fixtures/dynamic_finders/plugin_version/astra-widgets/change_log/changelog.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
v1.1.1
|
||||
- Fix: PHP Notice for address fixed.
|
||||
|
||||
v1.1.0
|
||||
- New: Add support for full FontAwesome library in widgets.
|
||||
- Fix: JS error in the WordPress admin panel causing errors in
|
||||
|
||||
v1.0.0
|
||||
- Initial release
|
||||
File diff suppressed because it is too large
Load Diff
258
spec/fixtures/dynamic_finders/plugin_version/avaibook/translation_file/languages/avaibook-pt_PT.po
vendored
Normal file
258
spec/fixtures/dynamic_finders/plugin_version/avaibook/translation_file/languages/avaibook-pt_PT.po
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
# Copyright (C) 2019 Carlos G. Cerro cgcerro@gmail.com
|
||||
# This file is distributed under the same license as the AvaiBook plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: AvaiBook 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/avaibook\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2019-06-25T12:50:01+02:00\n"
|
||||
"PO-Revision-Date: 2019-06-28 09:34+0200\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"X-Domain: avaibook\n"
|
||||
"Last-Translator: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: pt_PT\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "AvaiBook"
|
||||
msgstr "AvaiBook"
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "http://wordpress.org/plugins/avaibook/"
|
||||
msgstr "http://wordpress.org/plugins/avaibook/"
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Show Avaibook booking form in your wordpress"
|
||||
msgstr "Mostre o formulário de reserva Avaibook no seu Wordpress"
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Carlos G. Cerro cgcerro@gmail.com"
|
||||
msgstr ""
|
||||
|
||||
#: avaibook.php:239
|
||||
msgid "Show Avaibook book form 1"
|
||||
msgstr "Mostrar formulário AvaiBook 1"
|
||||
|
||||
#: avaibook.php:260
|
||||
msgid "Show Avaibook book form 2"
|
||||
msgstr "Mostrar formulário AvaiBook 2"
|
||||
|
||||
#: avaibook.php:282
|
||||
msgid "Show Avaibook book form 3"
|
||||
msgstr "Mostrar formulário AvaiBook 3"
|
||||
|
||||
#: includes/admin.php:3
|
||||
msgid "Form 1"
|
||||
msgstr "Formulário 1"
|
||||
|
||||
#: includes/admin.php:3
|
||||
msgid "Form 2"
|
||||
msgstr "Formulário 2"
|
||||
|
||||
#: includes/admin.php:3
|
||||
msgid "Form 3"
|
||||
msgstr "Formulário 3"
|
||||
|
||||
#: includes/admin.php:15
|
||||
msgid ""
|
||||
"You can define three types of form. Each one can have a different "
|
||||
"configuration or presentation."
|
||||
msgstr ""
|
||||
"É possível definir três tipos diferentes de formulários. Cada um com uma "
|
||||
"configuração ou apresentação diferente."
|
||||
|
||||
#: includes/admin.php:33
|
||||
msgid "Rental Id is mandatory with \"single\" rental type."
|
||||
msgstr ""
|
||||
"A identificação do alojamento é obrigatória no tipo de motor \"simples\"."
|
||||
|
||||
#: includes/admin.php:37
|
||||
msgid "Owner Id is mandatory with \"multiple\" rental type."
|
||||
msgstr ""
|
||||
"A identificação do alojamento é obrigatória no tipo de motor \"múltiplo\"."
|
||||
|
||||
#: includes/admin.php:41
|
||||
msgid "Configuration saved."
|
||||
msgstr "Configuração gravada."
|
||||
|
||||
#: includes/admin.php:47
|
||||
msgid "Form"
|
||||
msgstr "Formulário"
|
||||
|
||||
#: includes/admin.php:54
|
||||
msgid "AvaiBook configuration"
|
||||
msgstr "Configuração AvaiBook"
|
||||
|
||||
#: includes/admin.php:56
|
||||
msgid ""
|
||||
"Choose the type of Booking Engine you wish to link, and fill in the "
|
||||
"requested parameters (those marked with * are mandatory and you will find "
|
||||
"their value in your private area of AvaiBook)"
|
||||
msgstr ""
|
||||
"Escolha o tipo de motor de reservas que pretende utilizar. Preencha os "
|
||||
"campos obrigatórios (aqueles marcados com * são obrigatórios e encontrará o "
|
||||
"valor em sua área privada AvaiBook)"
|
||||
|
||||
#: includes/admin.php:61
|
||||
msgid "Booking Engine type"
|
||||
msgstr "Tipo de motor AvaiBook"
|
||||
|
||||
#: includes/admin.php:64
|
||||
msgid "Single"
|
||||
msgstr "Simples"
|
||||
|
||||
#: includes/admin.php:65
|
||||
msgid "Multiple"
|
||||
msgstr "Múltiplo"
|
||||
|
||||
#: includes/admin.php:67
|
||||
msgid ""
|
||||
"Choose the type of booking engine you want to use. To a single accommodation "
|
||||
"or to all your accommodations"
|
||||
msgstr ""
|
||||
"Escolha o tipo de motor de reservas que pretende utilizar. Para um único "
|
||||
"alojamento ou para todos os alojamentos"
|
||||
|
||||
#: includes/admin.php:73
|
||||
msgid "Rental Id"
|
||||
msgstr "ID de Alojamento"
|
||||
|
||||
#: includes/admin.php:75
|
||||
msgid "This is the AvaiBook accommodation Id"
|
||||
msgstr "Este é o identificador do alojamento"
|
||||
|
||||
#: includes/admin.php:79
|
||||
msgid "Reference"
|
||||
msgstr "Referência"
|
||||
|
||||
#: includes/admin.php:81 includes/admin.php:99
|
||||
msgid ""
|
||||
"(optional) the generated reserves will have this reference so that you can "
|
||||
"distinguish them"
|
||||
msgstr ""
|
||||
"(opcional) as reservas geradas terão esta referência anotada para que possa "
|
||||
"distingui-las"
|
||||
|
||||
#: includes/admin.php:92
|
||||
msgid "This is your customer id in AvaiBook"
|
||||
msgstr "Este é o seu ID de cliente no AvaiBook"
|
||||
|
||||
#: includes/admin.php:105
|
||||
msgid "Show rental units"
|
||||
msgstr "Mostrar unidades habitacionais"
|
||||
|
||||
#: includes/admin.php:106
|
||||
msgid "Show zones"
|
||||
msgstr "Mostrar zonas"
|
||||
|
||||
#: includes/admin.php:107
|
||||
msgid "Show people"
|
||||
msgstr "Mostrar pessoas"
|
||||
|
||||
#: includes/admin.php:108
|
||||
msgid "Behavior in the booking engine"
|
||||
msgstr "Comportamento no motor de reservas"
|
||||
|
||||
#: includes/admin.php:116
|
||||
msgid "Display options"
|
||||
msgstr "Opções de apresentação"
|
||||
|
||||
#: includes/admin.php:118
|
||||
msgid ""
|
||||
"Choose how you want your widget to be and what colors you want it to have. "
|
||||
"If you do not mark any of the options below your widget will only be a "
|
||||
"button."
|
||||
msgstr ""
|
||||
"Escolha como quer que seja o seu widget e que cores quer que ele tenha. Se "
|
||||
"não marcar nenhuma das opções, o widget será apenas um botão."
|
||||
|
||||
#: includes/admin.php:121
|
||||
msgid "title"
|
||||
msgstr "título"
|
||||
|
||||
#: includes/admin.php:122
|
||||
msgid "This text title will be showed in your form"
|
||||
msgstr "Este título será exibido no seu formulário"
|
||||
|
||||
#: includes/admin.php:127
|
||||
msgid "Request dates"
|
||||
msgstr "Pedir datas"
|
||||
|
||||
#: includes/admin.php:128
|
||||
msgid "show dates request's fields"
|
||||
msgstr "exibir campos de datas"
|
||||
|
||||
#: includes/admin.php:135
|
||||
msgid "Request guest number"
|
||||
msgstr "Pedir número de clientes"
|
||||
|
||||
#: includes/admin.php:136
|
||||
msgid "show guest's numbers field"
|
||||
msgstr "mostrar no campo o número de pessoas"
|
||||
|
||||
#: includes/admin.php:140
|
||||
msgid "Colour settings"
|
||||
msgstr "Configuração de cores"
|
||||
|
||||
#: includes/admin.php:141
|
||||
msgid "Set empty for keep your default style."
|
||||
msgstr "Mantenha a caixa vazia para deixar o seu estilo por defeito."
|
||||
|
||||
#: includes/admin.php:144
|
||||
msgid "Background colour"
|
||||
msgstr "Cor de fundo"
|
||||
|
||||
#: includes/admin.php:153
|
||||
msgid "Main colour"
|
||||
msgstr "Cor principal"
|
||||
|
||||
#: includes/admin.php:162
|
||||
msgid "Text colour"
|
||||
msgstr "Cor do texto"
|
||||
|
||||
#: includes/admin.php:176
|
||||
msgid "Save changes"
|
||||
msgstr "Guardar modificações"
|
||||
|
||||
#: includes/admin.php:181
|
||||
msgid "Options"
|
||||
msgstr "Opções"
|
||||
|
||||
#: includes/admin.php:183
|
||||
msgid "You can use this shortcode"
|
||||
msgstr "Pode usar o seguinte shortcode"
|
||||
|
||||
#: includes/admin.php:185
|
||||
msgid "Only copy this code, and put it where you want in your post or pages."
|
||||
msgstr "Basta copiar o código e colá-lo onde quiser nos seus posts ou páginas."
|
||||
|
||||
#: includes/admin.php:187
|
||||
msgid "Or you can use our widget"
|
||||
msgstr "Ou pode usar o nosso widget"
|
||||
|
||||
#: includes/admin.php:189
|
||||
msgid ""
|
||||
"Go to <a href=\"%s\">widgets section</a> and drag our widget \"avaibook%s\" "
|
||||
"where you want."
|
||||
msgstr ""
|
||||
"Vá até a seção <a href=\"%s\">widget </a> e arraste o nosso widget \"avaibook"
|
||||
"%s\" onde quiser."
|
||||
|
||||
#: includes/front.php:11
|
||||
msgid "Arrive date"
|
||||
msgstr "Data de chegada"
|
||||
|
||||
#: includes/front.php:16
|
||||
msgid "Departure date"
|
||||
msgstr "Data saída"
|
||||
|
||||
#: includes/front.php:24 includes/front.php:25
|
||||
msgid "Guest Num."
|
||||
msgstr "Número de pessoas."
|
||||
|
||||
#: includes/front.php:29
|
||||
msgid "search"
|
||||
msgstr "procurar"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user