Compare commits
376 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6da9540a97 | ||
|
|
44da286d5d | ||
|
|
96b6b81d78 | ||
|
|
de4f65e69b | ||
|
|
bce3b48ac7 | ||
|
|
2c1eb27f79 | ||
|
|
a423b15d53 | ||
|
|
162fcf4c2d | ||
|
|
2613fdcc6b | ||
|
|
fbabd509f0 | ||
|
|
a075c93e6f | ||
|
|
d2a8bf92d9 | ||
|
|
39459fb5a1 | ||
|
|
c11f4b9064 | ||
|
|
4fb47e1c3b | ||
|
|
1260a6480f | ||
|
|
598c6ebb69 | ||
|
|
289e2d80c1 | ||
|
|
cb7cd9aac2 | ||
|
|
99fca11958 | ||
|
|
ea020aa8a5 | ||
|
|
4d30fecc36 | ||
|
|
369bbbe084 | ||
|
|
257a4a458b | ||
|
|
0ddc3cc10b | ||
|
|
9c6f1daa83 | ||
|
|
cb9701eaef | ||
|
|
afc2fe2f79 | ||
|
|
0dd00645f8 | ||
|
|
c7919e3c75 | ||
|
|
fb812554f3 | ||
|
|
63094494d3 | ||
|
|
5ff73256e8 | ||
|
|
06d861c16c | ||
|
|
cfe1a40491 | ||
|
|
01fe047f2b | ||
|
|
a4dc0fb0e6 | ||
|
|
0905ad98c1 | ||
|
|
6a309a9624 | ||
|
|
7969e51231 | ||
|
|
933d6c7d0e | ||
|
|
3c879b2523 | ||
|
|
783d016bd1 | ||
|
|
1436122b01 | ||
|
|
922e4f993b | ||
|
|
16d79ec11a | ||
|
|
f08158342a | ||
|
|
be7437d117 | ||
|
|
1a76eb8a83 | ||
|
|
24851106bd | ||
|
|
46e3692a03 | ||
|
|
196fbab5b1 | ||
|
|
f9e6e75c0c | ||
|
|
61363a1985 | ||
|
|
2c639c8f4e | ||
|
|
3cdf77ce54 | ||
|
|
1719e5dd21 | ||
|
|
2436aa527c | ||
|
|
855b2b5c36 | ||
|
|
b78b86cea3 | ||
|
|
047eec686d | ||
|
|
ff28962660 | ||
|
|
6751ebd110 | ||
|
|
03fbe79152 | ||
|
|
9abba8fd01 | ||
|
|
787e4cef0b | ||
|
|
56de3e28f5 | ||
|
|
4c1aeaab3d | ||
|
|
f9366f6da6 | ||
|
|
a9f3624a9b | ||
|
|
3305692808 | ||
|
|
4c50336793 | ||
|
|
ed89ea4a78 | ||
|
|
58bde8c26a | ||
|
|
39d4e94fbb | ||
|
|
a87e394b6d | ||
|
|
b48d11374f | ||
|
|
a8f913c020 | ||
|
|
3f4877a3a0 | ||
|
|
5feb6ffe34 | ||
|
|
a5adcfec97 | ||
|
|
90b61d035e | ||
|
|
05c21fb0a8 | ||
|
|
28cdf8e649 | ||
|
|
d1f2781929 | ||
|
|
6b57da0d8a | ||
|
|
b38f94ef39 | ||
|
|
06e3c76ac6 | ||
|
|
885bf041c4 | ||
|
|
ffe8574c51 | ||
|
|
910d34c721 | ||
|
|
5fec3a97c5 | ||
|
|
37f7dddac7 | ||
|
|
05d912e658 | ||
|
|
4bd87b2953 | ||
|
|
a4c843e51e | ||
|
|
7f9295ad54 | ||
|
|
0ab3d16be9 | ||
|
|
93f2e18811 | ||
|
|
ccd7324590 | ||
|
|
7323e8aa08 | ||
|
|
035830d7bc | ||
|
|
eaaefe2cf5 | ||
|
|
9499caf7b8 | ||
|
|
a677cf87cd | ||
|
|
2fc872ae6f | ||
|
|
27d4d14303 | ||
|
|
434f8819a2 | ||
|
|
97ad2dc158 | ||
|
|
8c1b8b5fda | ||
|
|
e179b7ae66 | ||
|
|
3af18b4fcb | ||
|
|
f4ddff64e9 | ||
|
|
0f587c4292 | ||
|
|
cc7f284d93 | ||
|
|
ebe6c50e15 | ||
|
|
19a4671e59 | ||
|
|
e505afe9df | ||
|
|
2632c6ed86 | ||
|
|
2f5ad3a338 | ||
|
|
7ea45a5f9b | ||
|
|
9d06ffe83a | ||
|
|
11394eaa9f | ||
|
|
8353161451 | ||
|
|
cbc52b977f | ||
|
|
e0b47d7501 | ||
|
|
d92152a557 | ||
|
|
2cc243ac13 | ||
|
|
e735a68102 | ||
|
|
d50ee2217e | ||
|
|
e78d948f82 | ||
|
|
dd10991f93 | ||
|
|
99963c9b24 | ||
|
|
9acac36b85 | ||
|
|
460f10b4ad | ||
|
|
48f5e7c4ab | ||
|
|
866504c2ab | ||
|
|
ec6417feed | ||
|
|
b02f65888c | ||
|
|
9db97d0730 | ||
|
|
36a35279f2 | ||
|
|
d9f3c682d0 | ||
|
|
42dee6cfa9 | ||
|
|
d41e73727a | ||
|
|
9b2755020d | ||
|
|
91388a787a | ||
|
|
2690ab324f | ||
|
|
84993f7bd6 | ||
|
|
5b5cac925c | ||
|
|
854ad45d84 | ||
|
|
7078943b90 | ||
|
|
d59a4799f5 | ||
|
|
cac9d4cc71 | ||
|
|
8aff900d4a | ||
|
|
3c99593599 | ||
|
|
d14bc739c8 | ||
|
|
6060fc7a69 | ||
|
|
d79163fcb5 | ||
|
|
145cae912b | ||
|
|
058eac160f | ||
|
|
f38cac8d8a | ||
|
|
2e19a423fc | ||
|
|
52e3e25741 | ||
|
|
1201ecbfd3 | ||
|
|
75de6316d2 | ||
|
|
4dbef70bd2 | ||
|
|
a0b5fb1107 | ||
|
|
14800f1f6c | ||
|
|
78231becd9 | ||
|
|
da180e1e20 | ||
|
|
c48be5e980 | ||
|
|
98a71d3af6 | ||
|
|
111693ce9e | ||
|
|
d926520b29 | ||
|
|
1a6e359d02 | ||
|
|
46d7ce0a65 | ||
|
|
fd63bfd5fa | ||
|
|
0778d7e5f6 | ||
|
|
9cb53bbf43 | ||
|
|
a98e37918b | ||
|
|
1d18514ab5 | ||
|
|
75d6a16298 | ||
|
|
d0ce7cb5c5 | ||
|
|
fa0d068c30 | ||
|
|
33d5199f51 | ||
|
|
ac14ce71be | ||
|
|
f4bb6e521e | ||
|
|
5f8aa862b4 | ||
|
|
3621f4cc15 | ||
|
|
b6e36b2605 | ||
|
|
7b55570cbb | ||
|
|
308997523c | ||
|
|
90433d77c6 | ||
|
|
c4bc3bf0e7 | ||
|
|
e9638bee06 | ||
|
|
850662902b | ||
|
|
26867873e2 | ||
|
|
7f491c2403 | ||
|
|
776ca22e77 | ||
|
|
dec31b5a1c | ||
|
|
96dbe526cf | ||
|
|
3113e7309e | ||
|
|
1809c6c195 | ||
|
|
adb84ef7da | ||
|
|
824697490f | ||
|
|
62e01cb9d6 | ||
|
|
87c2f82b80 | ||
|
|
f887f8baa4 | ||
|
|
4d00d97be9 | ||
|
|
b0e946ee29 | ||
|
|
1220b9f47b | ||
|
|
12d2d0ffb0 | ||
|
|
4581113741 | ||
|
|
a20c769eae | ||
|
|
3259316cf1 | ||
|
|
9cc06234e4 | ||
|
|
1ee73268d7 | ||
|
|
f477620899 | ||
|
|
8a9dc1ce2c | ||
|
|
b584aa24bd | ||
|
|
8dfe78a210 | ||
|
|
7143cb5def | ||
|
|
e6c49d99b6 | ||
|
|
6e71f9771c | ||
|
|
452126b56a | ||
|
|
28dfd8b3b9 | ||
|
|
d3196bc03f | ||
|
|
0bff3231cd | ||
|
|
6e9d147dd0 | ||
|
|
9a7872a7c4 | ||
|
|
e8f10fb2db | ||
|
|
221f3fcbfd | ||
|
|
ab5153363f | ||
|
|
8576145d3f | ||
|
|
7908fb7d97 | ||
|
|
44b934540e | ||
|
|
9978595237 | ||
|
|
109c701e4f | ||
|
|
11f35d86ff | ||
|
|
fa3005f2b7 | ||
|
|
f30255d6d8 | ||
|
|
183df75112 | ||
|
|
105d06c8f8 | ||
|
|
82941906ca | ||
|
|
470fbb1ff3 | ||
|
|
8c6234879e | ||
|
|
689252c715 | ||
|
|
19cf00227b | ||
|
|
c9795dc560 | ||
|
|
188c8f31b2 | ||
|
|
76b2c067f6 | ||
|
|
01316ceac1 | ||
|
|
52f14c5f06 | ||
|
|
6782730d80 | ||
|
|
4235871a00 | ||
|
|
cb27a22fc4 | ||
|
|
e639d4eee3 | ||
|
|
d95b70f1c2 | ||
|
|
fb97553f7c | ||
|
|
b3b3bec6b0 | ||
|
|
baab7a49f6 | ||
|
|
6843fe700e | ||
|
|
0c193de70e | ||
|
|
e42ce414de | ||
|
|
6d347ada98 | ||
|
|
3638241513 | ||
|
|
1c30743a11 | ||
|
|
48d363031b | ||
|
|
d083719b9c | ||
|
|
7fd59b27f4 | ||
|
|
6f4b216bb0 | ||
|
|
5fa82a3f27 | ||
|
|
02d1e30b08 | ||
|
|
1e2d227c56 | ||
|
|
cfc895e658 | ||
|
|
3f789b39c4 | ||
|
|
16002576d2 | ||
|
|
7b0e352d29 | ||
|
|
da85729254 | ||
|
|
6a48f6c42b | ||
|
|
8eabcd9df3 | ||
|
|
6b89bc9f55 | ||
|
|
1e250796ca | ||
|
|
c73f9028f0 | ||
|
|
71c89371a9 | ||
|
|
9043ddca71 | ||
|
|
6c461e778d | ||
|
|
3f1a71c643 | ||
|
|
b0df6dcade | ||
|
|
ac0d2fb536 | ||
|
|
48f107021a | ||
|
|
64ac4ecf72 | ||
|
|
ddc680a9ae | ||
|
|
43b04da5a2 | ||
|
|
bc28dd392d | ||
|
|
0d2e1fee43 | ||
|
|
eaf2cec8c9 | ||
|
|
611d3dfd4d | ||
|
|
c4030d8267 | ||
|
|
630752787a | ||
|
|
c07ecc58cb | ||
|
|
89fccfe7b7 | ||
|
|
ceeb7e538b | ||
|
|
8dab57b59c | ||
|
|
7a00cd8db1 | ||
|
|
daa0915bca | ||
|
|
ca6b6a30d8 | ||
|
|
09f2640879 | ||
|
|
f61c55b350 | ||
|
|
78d0c2540c | ||
|
|
1d0426e816 | ||
|
|
103a4049c8 | ||
|
|
cbcb1dcb33 | ||
|
|
9c36293382 | ||
|
|
2fb36dc425 | ||
|
|
c717ba5a71 | ||
|
|
7572518e3b | ||
|
|
f670133a82 | ||
|
|
a6bbf41e82 | ||
|
|
622c16932a | ||
|
|
5fd7e0ed22 | ||
|
|
d9f6c71015 | ||
|
|
61a3106b3b | ||
|
|
20eb2d825d | ||
|
|
906557d2ec | ||
|
|
c1e278ea80 | ||
|
|
e2d616a53f | ||
|
|
c6802ccdd2 | ||
|
|
abd50fd037 | ||
|
|
4515be53b4 | ||
|
|
920a25bb25 | ||
|
|
648dd05069 | ||
|
|
713edcecca | ||
|
|
ac16a951c5 | ||
|
|
1043bcb267 | ||
|
|
22979a1a77 | ||
|
|
3039d2e7eb | ||
|
|
557dee2d8c | ||
|
|
a506adcb64 | ||
|
|
3bfb120646 | ||
|
|
43e613aa52 | ||
|
|
0d930ed605 | ||
|
|
2014f1e4b3 | ||
|
|
4889d17e0a | ||
|
|
494d31215d | ||
|
|
582bdea431 | ||
|
|
ecf7df9c01 | ||
|
|
a9760e8817 | ||
|
|
b32e990dd4 | ||
|
|
4320d2436f | ||
|
|
cba6e74b13 | ||
|
|
981bcf5fa2 | ||
|
|
1d79bc37d3 | ||
|
|
2fae3336ba | ||
|
|
cfb98c5139 | ||
|
|
b0260327c4 | ||
|
|
f65532e347 | ||
|
|
ff574b046c | ||
|
|
97c995b64c | ||
|
|
8361ec97e4 | ||
|
|
7a0bbc0acb | ||
|
|
66f5eca841 | ||
|
|
b53e6d1888 | ||
|
|
4b68fa8b60 | ||
|
|
54770c5a50 | ||
|
|
39fb2167f7 | ||
|
|
c33fef9c98 | ||
|
|
08a1117edf | ||
|
|
e14cbed56e | ||
|
|
56e2ab16cc | ||
|
|
d76d4b70f5 | ||
|
|
e223936a81 | ||
|
|
60d067c421 | ||
|
|
4102cf4688 | ||
|
|
dc977e6630 | ||
|
|
05deabd775 |
7
.codeclimate.yml
Normal file
7
.codeclimate.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
version: "2"
|
||||
# https://docs.codeclimate.com/docs/default-analysis-configuration#sample-codeclimateyml
|
||||
checks:
|
||||
method-complexity:
|
||||
enabled: true
|
||||
config:
|
||||
threshold: 15
|
||||
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "bundler"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
# Check for updates to GitHub Actions every weekday
|
||||
interval: "daily"
|
||||
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -9,14 +9,14 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
ruby: [2.5, 2.6, 2.7]
|
||||
ruby: [2.7, '3.0', 3.1, 3.2]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Ruby ${{ matrix.ruby }}
|
||||
uses: actions/setup-ruby@v1
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby }}
|
||||
|
||||
@@ -37,5 +37,6 @@ jobs:
|
||||
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
continue-on-error: true
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
56
.github/workflows/docker.yml
vendored
Normal file
56
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Build Docker Images
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
release:
|
||||
types: [published]
|
||||
schedule:
|
||||
- cron: "0 7 * * *"
|
||||
|
||||
jobs:
|
||||
images:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout sources
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set tag to latest
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
|
||||
|
||||
- name: Set tag to release name
|
||||
if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
echo "DOCKER_TAG=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Check if DOCKER_TAG is set
|
||||
if: env.DOCKER_TAG == ''
|
||||
run: |
|
||||
echo DOCKER_TAG is not set!
|
||||
exit 1
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
id: buildx
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.2.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
push: true
|
||||
tags: wpscanteam/wpscan:${{ env.DOCKER_TAG }}
|
||||
6
.github/workflows/gempush.yml
vendored
6
.github/workflows/gempush.yml
vendored
@@ -10,11 +10,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Ruby 2.6
|
||||
uses: actions/setup-ruby@v1
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6.x
|
||||
ruby-version: 2.6
|
||||
|
||||
#- name: Publish to GPR
|
||||
# run: |
|
||||
|
||||
34
.rubocop.yml
34
.rubocop.yml
@@ -1,25 +1,21 @@
|
||||
require: rubocop-performance
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.5
|
||||
NewCops: enable
|
||||
SuggestExtensions: false
|
||||
TargetRubyVersion: 2.7
|
||||
Exclude:
|
||||
- '*.gemspec'
|
||||
- 'vendor/**/*'
|
||||
Layout/EmptyLinesAroundAttributeAccessor:
|
||||
Enabled: true
|
||||
Layout/LineLength:
|
||||
Max: 120
|
||||
Layout/SpaceAroundMethodCallOperator:
|
||||
Enabled: true
|
||||
Lint/DeprecatedOpenSSLConstant:
|
||||
Enabled: true
|
||||
Lint/ConstantDefinitionInBlock:
|
||||
Enabled: false
|
||||
Lint/MissingSuper:
|
||||
Enabled: false
|
||||
Lint/UriEscapeUnescape:
|
||||
Enabled: false
|
||||
Lint/RaiseException:
|
||||
Enabled: true
|
||||
Lint/StructNewOverride:
|
||||
Enabled: true
|
||||
Metrics/AbcSize:
|
||||
Max: 25
|
||||
Max: 27
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
@@ -28,27 +24,19 @@ Metrics/ClassLength:
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 8
|
||||
Max: 10
|
||||
Metrics/MethodLength:
|
||||
Max: 20
|
||||
Exclude:
|
||||
- 'app/controllers/enumeration/cli_options.rb'
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 11
|
||||
Style/ClassVars:
|
||||
Enabled: false
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
Style/ExponentialNotation:
|
||||
Enabled: true
|
||||
Style/FormatStringToken:
|
||||
Enabled: false
|
||||
Style/HashEachMethods:
|
||||
Enabled: true
|
||||
Style/HashTransformKeys:
|
||||
Enabled: true
|
||||
Style/HashTransformValues:
|
||||
Enabled: true
|
||||
Style/NumericPredicate:
|
||||
Exclude:
|
||||
- 'app/controllers/vuln_api.rb'
|
||||
Style/SlicingWithRange:
|
||||
Enabled: true
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.7.1
|
||||
3.0.2
|
||||
|
||||
21
Dockerfile
21
Dockerfile
@@ -1,16 +1,16 @@
|
||||
FROM ruby:2.6.3-alpine AS builder
|
||||
LABEL maintainer="WPScan Team <team@wpscan.org>"
|
||||
FROM ruby:3.0.2-alpine AS builder
|
||||
LABEL maintainer="WPScan Team <contact@wpscan.com>"
|
||||
|
||||
ARG BUNDLER_ARGS="--jobs=8 --without test development"
|
||||
|
||||
RUN echo "gem: --no-ri --no-rdoc" > /etc/gemrc
|
||||
RUN echo "install: --no-document --no-post-install-message\nupdate: --no-document --no-post-install-message" > /etc/gemrc
|
||||
|
||||
COPY . /wpscan
|
||||
|
||||
RUN apk add --no-cache git libcurl ruby-dev libffi-dev make gcc musl-dev zlib-dev procps sqlite-dev && \
|
||||
bundle install --system --clean --no-cache --gemfile=/wpscan/Gemfile $BUNDLER_ARGS && \
|
||||
# temp fix for https://github.com/bundler/bundler/issues/6680
|
||||
rm -rf /usr/local/bundle/cache
|
||||
bundle config force_ruby_platform true && \
|
||||
bundle config disable_version_check 'true' && \
|
||||
bundle config without "test development" && \
|
||||
bundle config path.system 'true' && \
|
||||
bundle install --gemfile=/wpscan/Gemfile --jobs=8
|
||||
|
||||
WORKDIR /wpscan
|
||||
RUN rake install --trace
|
||||
@@ -19,8 +19,9 @@ RUN rake install --trace
|
||||
RUN chmod -R a+r /usr/local/bundle
|
||||
|
||||
|
||||
FROM ruby:2.6.3-alpine
|
||||
LABEL maintainer="WPScan Team <team@wpscan.org>"
|
||||
FROM ruby:3.0.2-alpine
|
||||
LABEL maintainer="WPScan Team <contact@wpscan.com>"
|
||||
LABEL org.opencontainers.image.source https://github.com/wpscanteam/wpscan
|
||||
|
||||
RUN adduser -h /wpscan -g WPScan -D wpscan
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -27,7 +27,7 @@ Example cases which do not require a commercial license, and thus fall under the
|
||||
- Using WPScan to test your own systems.
|
||||
- Any non-commercial use of WPScan.
|
||||
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - contact@wpscan.com.
|
||||
|
||||
Free-use Terms and Conditions;
|
||||
|
||||
|
||||
34
README.md
34
README.md
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<a href="https://wpscan.org/">
|
||||
<a href="https://wpscan.com/">
|
||||
<img src="https://raw.githubusercontent.com/wpscanteam/wpscan/gh-pages/images/wpscan_logo.png" alt="WPScan logo">
|
||||
</a>
|
||||
</p>
|
||||
@@ -10,11 +10,12 @@
|
||||
WordPress Security Scanner
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://wpscan.org/" title="homepage" target="_blank">Homepage</a> - <a href="https://wpscan.io/" title="wpscan.io" target="_blank">WPScan.io</a> - <a href="https://wpvulndb.com/" title="vulnerability database" target="_blank">Vulnerability Database</a> - <a href="https://wordpress.org/plugins/wpscan/" title="wordpress security plugin" target="_blank">WordPress Security Plugin</a>
|
||||
<a href="https://wpscan.com/" title="homepage" target="_blank">WPScan WordPress Vulnerability Database</a> - <a href="https://wordpress.org/plugins/wpscan/" title="wordpress security plugin" target="_blank">WordPress Security Plugin</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://badge.fury.io/rb/wpscan" target="_blank"><img src="https://badge.fury.io/rb/wpscan.svg"></a>
|
||||
<a href="https://hub.docker.com/r/wpscanteam/wpscan/" target="_blank"><img src="https://img.shields.io/docker/pulls/wpscanteam/wpscan.svg"></a>
|
||||
<a href="https://github.com/wpscanteam/wpscan/actions?query=workflow%3ABuild" target="_blank"><img src="https://github.com/wpscanteam/wpscan/workflows/Build/badge.svg"></a>
|
||||
<a href="https://codeclimate.com/github/wpscanteam/wpscan" target="_blank"><img src="https://codeclimate.com/github/wpscanteam/wpscan/badges/gpa.svg"></a>
|
||||
</p>
|
||||
@@ -24,10 +25,10 @@
|
||||
## Prerequisites
|
||||
|
||||
- (Optional but highly recommended: [RVM](https://rvm.io/rvm/install))
|
||||
- Ruby >= 2.3 - Recommended: latest
|
||||
- Ruby 2.5.0 to 2.5.3 can cause an 'undefined symbol: rmpd_util_str_to_d' error in some systems, see [#1283](https://github.com/wpscanteam/wpscan/issues/1283)
|
||||
- Curl >= 7.21 - Recommended: latest
|
||||
- Ruby >= 2.7 - Recommended: latest
|
||||
- Curl >= 7.72 - Recommended: latest
|
||||
- The 7.29 has a segfault
|
||||
- The < 7.72 could result in `Stream error in the HTTP/2 framing layer` in some cases
|
||||
- RubyGems - Recommended: latest
|
||||
- Nokogiri might require packages to be installed via your package manager depending on your OS, see https://nokogiri.org/tutorials/installing_nokogiri.html
|
||||
|
||||
@@ -35,6 +36,12 @@
|
||||
|
||||
When using a pentesting distubution (such as Kali Linux), it is recommended to install/update wpscan via the package manager if available.
|
||||
|
||||
### In macOSX via Homebrew
|
||||
|
||||
```shell
|
||||
brew install wpscanteam/tap/wpscan
|
||||
```
|
||||
|
||||
### From RubyGems
|
||||
|
||||
```shell
|
||||
@@ -47,7 +54,7 @@ On MacOSX, if a ```Gem::FilePermissionError``` is raised due to the Apple's Syst
|
||||
|
||||
You can update the local database by using ```wpscan --update```
|
||||
|
||||
Updating WPScan itself is either done via ```gem update wpscan``` or the packages manager (this is quite important for distributions such as in Kali Linux: ```apt-get update && apt-get upgrade```) depending how WPScan was (pre)installed
|
||||
Updating WPScan itself is either done via ```gem update wpscan``` or the packages manager (this is quite important for distributions such as in Kali Linux: ```apt-get update && apt-get upgrade```) depending on how WPScan was (pre)installed
|
||||
|
||||
# Docker
|
||||
|
||||
@@ -80,9 +87,16 @@ For more options, open a terminal and type ```wpscan --help``` (if you built wps
|
||||
|
||||
The DB is located at ~/.wpscan/db
|
||||
|
||||
## Vulnerability Database
|
||||
## Optional: WordPress Vulnerability Database API
|
||||
|
||||
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/).
|
||||
The WPScan CLI tool uses the [WordPress Vulnerability Database API](https://wpscan.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 [WPScan.com](https://wpscan.com/register).
|
||||
|
||||
Up to **25** API requests per day are given free of charge, that should be suitable to scan most WordPress websites at least once per day. When the daily 25 API requests are exhausted, WPScan will continue to work as normal but without any vulnerability data.
|
||||
|
||||
### How many API requests do you need?
|
||||
|
||||
- Our WordPress scanner makes one API request for the WordPress version, one request per installed plugin and one request per installed theme.
|
||||
- On average, a WordPress website has 22 installed plugins.
|
||||
|
||||
## Load CLI options from file/s
|
||||
|
||||
@@ -121,7 +135,7 @@ The feature mentioned above is useful to keep the API Token in a config file and
|
||||
|
||||
```yml
|
||||
cli_options:
|
||||
api_token: YOUR_API_TOKEN
|
||||
api_token: 'YOUR_API_TOKEN'
|
||||
```
|
||||
|
||||
## Load API Token From ENV (since v3.7.10)
|
||||
@@ -176,7 +190,7 @@ Example cases which do not require a commercial license, and thus fall under the
|
||||
- Using WPScan to test your own systems.
|
||||
- Any non-commercial use of WPScan.
|
||||
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - contact@wpscan.com.
|
||||
|
||||
Free-use Terms and Conditions;
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ module WPScan
|
||||
def cli_options
|
||||
[OptURL.new(['--url URL', 'The URL of the blog to scan'],
|
||||
required_unless: %i[update help hh version], default_protocol: 'http')] +
|
||||
super.drop(1) + # delete the --url from CMSScanner
|
||||
super.drop(2) + # delete the --url and --force from CMSScanner
|
||||
[
|
||||
OptChoice.new(['--server SERVER', 'Force the supplied server module to be loaded'],
|
||||
choices: %w[apache iis nginx],
|
||||
normalize: %i[downcase to_sym],
|
||||
advanced: true),
|
||||
OptBoolean.new(['--force', 'Do not check if the target is running WordPress']),
|
||||
OptBoolean.new(['--force', 'Do not check if the target is running WordPress or returns a 403']),
|
||||
OptBoolean.new(['--[no-]update', 'Whether or not to update the Database'])
|
||||
]
|
||||
end
|
||||
@@ -39,7 +39,7 @@ module WPScan
|
||||
output('@notice', msg: 'It seems like you have not updated the database for some time.')
|
||||
print '[?] Do you want to update now? [Y]es [N]o, default: [N]'
|
||||
|
||||
/^y/i.match?(Readline.readline) ? true : false
|
||||
/^y/i.match?(Readline.readline)
|
||||
end
|
||||
|
||||
def update_db
|
||||
|
||||
@@ -170,6 +170,12 @@ module WPScan
|
||||
['--users-detection MODE',
|
||||
'Use the supplied mode to enumerate Users, instead of the global (--detection-mode) mode.'],
|
||||
choices: %w[mixed passive aggressive], normalize: :to_sym, advanced: true
|
||||
),
|
||||
OptRegexp.new(
|
||||
[
|
||||
'--exclude-usernames REGEXP_OR_STRING',
|
||||
'Exclude usernames matching the Regexp/string (case insensitive). Regexp delimiters are not required.'
|
||||
], options: Regexp::IGNORECASE
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
@@ -17,33 +17,40 @@ module WPScan
|
||||
'Maximum number of passwords to send by request with XMLRPC multicall'],
|
||||
default: 500),
|
||||
OptChoice.new(['--password-attack ATTACK',
|
||||
'Force the supplied attack to be used rather than automatically determining one.'],
|
||||
'Force the supplied attack to be used rather than automatically determining one.',
|
||||
'Multicall will only work against WP < 4.4'],
|
||||
choices: %w[wp-login xmlrpc xmlrpc-multicall],
|
||||
normalize: %i[downcase underscore to_sym])
|
||||
normalize: %i[downcase underscore to_sym]),
|
||||
OptString.new(['--login-uri URI', 'The URI of the login page if different from /wp-login.php'])
|
||||
]
|
||||
end
|
||||
|
||||
def attack_opts
|
||||
@attack_opts ||= {
|
||||
show_progression: user_interaction?,
|
||||
multicall_max_passwords: ParsedCli.multicall_max_passwords
|
||||
}
|
||||
end
|
||||
|
||||
def run
|
||||
return unless ParsedCli.passwords
|
||||
|
||||
if user_interaction?
|
||||
output('@info',
|
||||
msg: "Performing password attack on #{attacker.titleize} against #{users.size} user/s")
|
||||
end
|
||||
|
||||
attack_opts = {
|
||||
show_progression: user_interaction?,
|
||||
multicall_max_passwords: ParsedCli.multicall_max_passwords
|
||||
}
|
||||
|
||||
begin
|
||||
found = []
|
||||
|
||||
attacker.attack(users, passwords(ParsedCli.passwords), attack_opts) do |user|
|
||||
if user_interaction?
|
||||
output('@info',
|
||||
msg: "Performing password attack on #{attacker.titleize} against #{users.size} user/s")
|
||||
end
|
||||
|
||||
attacker.attack(users, ParsedCli.passwords, attack_opts) do |user|
|
||||
found << user
|
||||
|
||||
attacker.progress_bar.log("[SUCCESS] - #{user.username} / #{user.password}")
|
||||
end
|
||||
rescue Error::NoLoginInterfaceDetected => e
|
||||
# TODO: Maybe output that in JSON as well.
|
||||
output('@notice', msg: e.to_s) if user_interaction?
|
||||
ensure
|
||||
output('users', users: found)
|
||||
end
|
||||
@@ -65,6 +72,8 @@ module WPScan
|
||||
|
||||
case ParsedCli.password_attack
|
||||
when :wp_login
|
||||
raise Error::NoLoginInterfaceDetected unless target.login_url
|
||||
|
||||
Finders::Passwords::WpLogin.new(target)
|
||||
when :xmlrpc
|
||||
raise Error::XMLRPCNotDetected unless xmlrpc
|
||||
@@ -81,8 +90,8 @@ module WPScan
|
||||
def xmlrpc_get_users_blogs_enabled?
|
||||
if xmlrpc&.enabled? &&
|
||||
xmlrpc.available_methods.include?('wp.getUsersBlogs') &&
|
||||
xmlrpc.method_call('wp.getUsersBlogs', [SecureRandom.hex[0, 6], SecureRandom.hex[0, 4]])
|
||||
.run.body !~ /XML\-RPC services are disabled/
|
||||
!xmlrpc.method_call('wp.getUsersBlogs', [SecureRandom.hex[0, 6], SecureRandom.hex[0, 4]])
|
||||
.run.body.match?(/>\s*405\s*</)
|
||||
|
||||
true
|
||||
else
|
||||
@@ -100,8 +109,10 @@ module WPScan
|
||||
else
|
||||
Finders::Passwords::XMLRPC.new(xmlrpc)
|
||||
end
|
||||
else
|
||||
elsif target.login_url
|
||||
Finders::Passwords::WpLogin.new(target)
|
||||
else
|
||||
raise Error::NoLoginInterfaceDetected
|
||||
end
|
||||
end
|
||||
|
||||
@@ -113,15 +124,6 @@ module WPScan
|
||||
acc << Model::User.new(elem.chomp)
|
||||
end
|
||||
end
|
||||
|
||||
# @param [ String ] wordlist_path
|
||||
#
|
||||
# @return [ Array<String> ]
|
||||
def passwords(wordlist_path)
|
||||
@passwords ||= File.open(wordlist_path).reduce([]) do |acc, elem|
|
||||
acc << elem.chomp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,10 @@ module WPScan
|
||||
|
||||
def cli_options
|
||||
[
|
||||
OptString.new(['--api-token TOKEN', 'The WPVulnDB API Token to display vulnerability data'])
|
||||
OptString.new(
|
||||
['--api-token TOKEN',
|
||||
'The WPScan API Token to display vulnerability data, available at https://wpscan.com/profile']
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
@@ -19,7 +22,7 @@ module WPScan
|
||||
|
||||
api_status = DB::VulnApi.status
|
||||
|
||||
raise Error::InvalidApiToken if api_status['error']
|
||||
raise Error::InvalidApiToken if api_status['status'] == 'forbidden'
|
||||
raise Error::ApiLimitReached if api_status['requests_remaining'] == 0
|
||||
raise api_status['http_error'] if api_status['http_error']
|
||||
end
|
||||
|
||||
@@ -7,7 +7,11 @@ module WPScan
|
||||
class KnownLocations < CMSScanner::Finders::Finder
|
||||
include CMSScanner::Finders::Finder::Enumerator
|
||||
|
||||
SQL_PATTERN = /(?:DROP|(?:UN)?LOCK|CREATE) TABLE|INSERT INTO/.freeze
|
||||
def valid_response_codes
|
||||
@valid_response_codes ||= [200, 206].freeze
|
||||
end
|
||||
|
||||
SQL_PATTERN = /(?:DROP|(?:UN)?LOCK|CREATE|ALTER) (?:TABLE|DATABASE)|INSERT INTO/.freeze
|
||||
|
||||
# @param [ Hash ] opts
|
||||
# @option opts [ String ] :list
|
||||
@@ -17,7 +21,7 @@ module WPScan
|
||||
def aggressive(opts = {})
|
||||
found = []
|
||||
|
||||
enumerate(potential_urls(opts), opts.merge(check_full_response: 200)) do |res|
|
||||
enumerate(potential_urls(opts), opts.merge(check_full_response: valid_response_codes)) do |res|
|
||||
if res.effective_url.end_with?('.zip')
|
||||
next unless %r{\Aapplication/zip}i.match?(res.headers['Content-Type'])
|
||||
else
|
||||
@@ -39,18 +43,57 @@ module WPScan
|
||||
#
|
||||
# @return [ Hash ]
|
||||
def potential_urls(opts = {})
|
||||
urls = {}
|
||||
domain_name = (PublicSuffix.domain(target.uri.host) || target.uri.host)[/(^[\w|-]+)/, 1]
|
||||
urls = {}
|
||||
index = 0
|
||||
|
||||
File.open(opts[:list]).each_with_index do |path, index|
|
||||
path.gsub!('{domain_name}', domain_name)
|
||||
File.open(opts[:list]).each do |path|
|
||||
path.chomp!
|
||||
|
||||
urls[target.url(path.chomp)] = index
|
||||
if path.include?('{domain_name}')
|
||||
urls[target.url(path.gsub('{domain_name}', domain_name))] = index
|
||||
|
||||
if domain_name != domain_name_with_sub
|
||||
urls[target.url(path.gsub('{domain_name}', domain_name_with_sub))] = index + 1
|
||||
|
||||
index += 1
|
||||
end
|
||||
else
|
||||
urls[target.url(path)] = index
|
||||
end
|
||||
|
||||
index += 1
|
||||
end
|
||||
|
||||
urls
|
||||
end
|
||||
|
||||
def domain_name
|
||||
@domain_name ||= if Resolv::AddressRegex.match?(target.uri.host)
|
||||
target.uri.host
|
||||
else
|
||||
(PublicSuffix.domain(target.uri.host) || target.uri.host)[/(^[\w|-]+)/, 1]
|
||||
end
|
||||
end
|
||||
|
||||
def domain_name_with_sub
|
||||
@domain_name_with_sub ||=
|
||||
if Resolv::AddressRegex.match?(target.uri.host)
|
||||
target.uri.host
|
||||
else
|
||||
parsed = PublicSuffix.parse(target.uri.host)
|
||||
|
||||
if parsed.subdomain
|
||||
parsed.subdomain.gsub(".#{parsed.tld}", '')
|
||||
elsif parsed.domain
|
||||
parsed.domain.gsub(".#{parsed.tld}", '')
|
||||
else
|
||||
target.uri.host
|
||||
end
|
||||
end
|
||||
rescue PublicSuffix::DomainNotAllowed
|
||||
@domain_name_with_sub = target.uri.host
|
||||
end
|
||||
|
||||
def create_progress_bar(opts = {})
|
||||
super(opts.merge(title: ' Checking DB Exports -'))
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ require_relative 'interesting_findings/multisite'
|
||||
require_relative 'interesting_findings/debug_log'
|
||||
require_relative 'interesting_findings/backup_db'
|
||||
require_relative 'interesting_findings/mu_plugins'
|
||||
require_relative 'interesting_findings/php_disabled'
|
||||
require_relative 'interesting_findings/registration'
|
||||
require_relative 'interesting_findings/tmm_db_migrate'
|
||||
require_relative 'interesting_findings/upload_sql_dump'
|
||||
@@ -26,7 +27,7 @@ module WPScan
|
||||
%w[
|
||||
Readme DebugLog FullPathDisclosure BackupDB DuplicatorInstallerLog
|
||||
Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate
|
||||
UploadSQLDump EmergencyPwdResetScript WPCron
|
||||
UploadSQLDump EmergencyPwdResetScript WPCron PHPDisabled
|
||||
].each do |f|
|
||||
finders << InterestingFindings.const_get(f).new(target)
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
def aggressive(_opts = {})
|
||||
path = 'installer-log.txt'
|
||||
|
||||
return unless /DUPLICATOR INSTALL-LOG/.match?(target.head_and_get(path).body)
|
||||
return unless /DUPLICATOR(-|\s)?(PRO|LITE)?:? INSTALL-LOG/i.match?(target.head_and_get(path).body)
|
||||
|
||||
Model::DuplicatorInstallerLog.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ module WPScan
|
||||
class MuPlugins < CMSScanner::Finders::Finder
|
||||
# @return [ InterestingFinding ]
|
||||
def passive(_opts = {})
|
||||
pattern = %r{#{target.content_dir}/mu\-plugins/}i
|
||||
pattern = %r{#{target.content_dir}/mu-plugins/}i
|
||||
|
||||
target.in_scope_uris(target.homepage_res, '(//@href|//@src)[contains(., "mu-plugins")]') do |uri|
|
||||
next unless uri.path&.match?(pattern)
|
||||
|
||||
@@ -12,8 +12,8 @@ module WPScan
|
||||
location = res.headers_hash['location']
|
||||
|
||||
return unless [200, 302].include?(res.code)
|
||||
return if res.code == 302 && location =~ /wp-login\.php\?action=register/
|
||||
return unless res.code == 200 || res.code == 302 && location =~ /wp-signup\.php/
|
||||
return if res.code == 302 && location&.include?('wp-login.php?action=register')
|
||||
return unless res.code == 200 || (res.code == 302 && location&.include?('wp-signup.php'))
|
||||
|
||||
target.multisite = true
|
||||
|
||||
|
||||
21
app/finders/interesting_findings/php_disabled.rb
Normal file
21
app/finders/interesting_findings/php_disabled.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Finders
|
||||
module InterestingFindings
|
||||
# See https://github.com/wpscanteam/wpscan/issues/1593
|
||||
class PHPDisabled < CMSScanner::Finders::Finder
|
||||
PATTERN = /\$wp_version =/.freeze
|
||||
|
||||
# @return [ InterestingFinding ]
|
||||
def aggressive(_opts = {})
|
||||
path = 'wp-includes/version.php'
|
||||
|
||||
return unless PATTERN.match?(target.head_and_get(path).body)
|
||||
|
||||
Model::PHPDisabled.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -21,7 +21,7 @@ module WPScan
|
||||
|
||||
def passive_from_css_href(res, opts)
|
||||
target.in_scope_uris(res, '//link/@href[contains(., "style.css")]') do |uri|
|
||||
next unless uri.path =~ %r{/themes/([^\/]+)/style.css\z}i
|
||||
next unless uri.path =~ %r{/themes/([^/]+)/style.css\z}i
|
||||
|
||||
return create_theme(Regexp.last_match[1], uri.to_s, opts)
|
||||
end
|
||||
@@ -33,7 +33,7 @@ module WPScan
|
||||
code = tag.text.to_s
|
||||
next if code.empty?
|
||||
|
||||
next unless code =~ %r{#{item_code_pattern('themes')}\\?/style\.css[^"'\( ]*}i
|
||||
next unless code =~ %r{#{item_code_pattern('themes')}\\?/style\.css[^"'( ]*}i
|
||||
|
||||
return create_theme(Regexp.last_match[1], Regexp.last_match[0].strip, opts)
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module WPScan
|
||||
def passive(opts = {})
|
||||
found = []
|
||||
|
||||
slugs = items_from_links('themes', false) + items_from_codes('themes', false)
|
||||
slugs = items_from_links('themes', uniq: false) + items_from_codes('themes', uniq: false)
|
||||
|
||||
slugs.each_with_object(Hash.new(0)) { |slug, counts| counts[slug] += 1 }.each do |slug, occurences|
|
||||
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 2 * occurences))
|
||||
|
||||
@@ -13,7 +13,7 @@ module WPScan
|
||||
|
||||
def valid_credentials?(response)
|
||||
response.code == 302 &&
|
||||
[*response.headers['Set-Cookie']]&.any? { |cookie| cookie =~ /wordpress_logged_in_/i }
|
||||
Array(response.headers['Set-Cookie'])&.any? { |cookie| cookie =~ /wordpress_logged_in_/i }
|
||||
end
|
||||
|
||||
def errored_response?(response)
|
||||
|
||||
@@ -12,7 +12,7 @@ module WPScan
|
||||
end
|
||||
|
||||
def valid_credentials?(response)
|
||||
response.code == 200 && response.body =~ /blogName/
|
||||
response.code == 200 && response.body.include?('blogName')
|
||||
end
|
||||
|
||||
def errored_response?(response)
|
||||
|
||||
@@ -22,8 +22,30 @@ module WPScan
|
||||
target.multi_call(methods, cache_ttl: 0).run
|
||||
end
|
||||
|
||||
# @param [ IO ] file
|
||||
# @param [ Integer ] passwords_size
|
||||
# @return [ Array<String> ] The passwords from the last checked position in the file until there are
|
||||
# passwords_size passwords retrieved
|
||||
def passwords_from_wordlist(file, passwords_size)
|
||||
pwds = []
|
||||
added_pwds = 0
|
||||
|
||||
return pwds if passwords_size.zero?
|
||||
|
||||
# Make sure that the main code does not call #sysseek or #count etc
|
||||
# otherwise the file descriptor will be set to somwehere else
|
||||
file.each_line(chomp: true) do |line|
|
||||
pwds << line
|
||||
added_pwds += 1
|
||||
|
||||
break if added_pwds == passwords_size
|
||||
end
|
||||
|
||||
pwds
|
||||
end
|
||||
|
||||
# @param [ Array<Model::User> ] users
|
||||
# @param [ Array<String> ] passwords
|
||||
# @param [ String ] wordlist_path
|
||||
# @param [ Hash ] opts
|
||||
# @option opts [ Boolean ] :show_progression
|
||||
# @option opts [ Integer ] :multicall_max_passwords
|
||||
@@ -33,18 +55,22 @@ module WPScan
|
||||
# TODO: Make rubocop happy about metrics etc
|
||||
#
|
||||
# rubocop:disable all
|
||||
def attack(users, passwords, opts = {})
|
||||
wordlist_index = 0
|
||||
def attack(users, wordlist_path, opts = {})
|
||||
checked_passwords = 0
|
||||
wordlist = File.open(wordlist_path)
|
||||
wordlist_size = wordlist.count
|
||||
max_passwords = opts[:multicall_max_passwords]
|
||||
current_passwords_size = passwords_size(max_passwords, users.size)
|
||||
|
||||
create_progress_bar(total: (passwords.size / current_passwords_size.round(1)).ceil,
|
||||
create_progress_bar(total: (wordlist_size / current_passwords_size.round(1)).ceil,
|
||||
show_progression: opts[:show_progression])
|
||||
|
||||
wordlist.sysseek(0) # reset the descriptor to the beginning of the file as it changed with #count
|
||||
|
||||
loop do
|
||||
current_users = users.select { |user| user.password.nil? }
|
||||
current_passwords = passwords[wordlist_index, current_passwords_size]
|
||||
wordlist_index += current_passwords_size
|
||||
current_users = users.select { |user| user.password.nil? }
|
||||
current_passwords = passwords_from_wordlist(wordlist, current_passwords_size)
|
||||
checked_passwords += current_passwords_size
|
||||
|
||||
break if current_users.empty? || current_passwords.nil? || current_passwords.empty?
|
||||
|
||||
@@ -75,9 +101,9 @@ module WPScan
|
||||
progress_bar.stop
|
||||
break
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
progress_bar.total = progress_bar.progress + ((passwords.size - wordlist_index) / current_passwords_size.round(1)).ceil
|
||||
progress_bar.total = progress_bar.progress + ((wordlist_size - checked_passwords) / current_passwords_size.round(1)).ceil
|
||||
rescue ProgressBar::InvalidProgressError
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ module WPScan
|
||||
#
|
||||
# @return [ String, nil ] The version number detected from the stable tag
|
||||
def from_stable_tag(body)
|
||||
return unless body =~ /\b(?:stable tag|version):\s*(?!trunk)([0-9a-z\.-]+)/i
|
||||
return unless body =~ /\b(?:stable tag|version):\s*(?!trunk)([0-9a-z.-]+)/i
|
||||
|
||||
number = Regexp.last_match[1]
|
||||
|
||||
@@ -59,13 +59,13 @@ module WPScan
|
||||
#
|
||||
# @return [ String, nil ] The best version number detected from the changelog section
|
||||
def from_changelog_section(body)
|
||||
extracted_versions = body.scan(%r{[=]+\s+(?:v(?:ersion)?\s*)?([0-9\.-]+)[ \ta-z0-9\(\)\.\-\/]*[=]+}i)
|
||||
extracted_versions = body.scan(/^=+\s+(?:v(?:ersion)?\s*)?([0-9.-]+)[^=]*=+$/i)
|
||||
|
||||
return if extracted_versions.nil? || extracted_versions.empty?
|
||||
|
||||
extracted_versions.flatten!
|
||||
# must contain at least one number
|
||||
extracted_versions = extracted_versions.select { |x| x =~ /[0-9]+/ }
|
||||
extracted_versions = extracted_versions.grep(/[0-9]+/)
|
||||
|
||||
sorted = extracted_versions.sort do |x, y|
|
||||
Gem::Version.new(x) <=> Gem::Version.new(y)
|
||||
|
||||
@@ -30,7 +30,7 @@ module WPScan
|
||||
|
||||
# @return [ Version ]
|
||||
def style_version
|
||||
return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z\.-]+)/i
|
||||
return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z.-]+)/i
|
||||
|
||||
Model::Version.new(
|
||||
Regexp.last_match[1],
|
||||
|
||||
@@ -6,10 +6,21 @@ require_relative 'users/oembed_api'
|
||||
require_relative 'users/rss_generator'
|
||||
require_relative 'users/author_id_brute_forcing'
|
||||
require_relative 'users/login_error_messages'
|
||||
require_relative 'users/yoast_seo_author_sitemap.rb'
|
||||
require_relative 'users/author_sitemap'
|
||||
require_relative 'users/yoast_seo_author_sitemap'
|
||||
|
||||
module WPScan
|
||||
module Finders
|
||||
# Specific Finders container to filter the usernames found
|
||||
# and remove the ones matching ParsedCli.exclude_username if supplied
|
||||
class UsersFinders < SameTypeFinders
|
||||
def filter_findings
|
||||
findings.delete_if { |user| ParsedCli.exclude_usernames.match?(user.username) } if ParsedCli.exclude_usernames
|
||||
|
||||
findings
|
||||
end
|
||||
end
|
||||
|
||||
module Users
|
||||
# Users Finder
|
||||
class Base
|
||||
@@ -22,10 +33,15 @@ module WPScan
|
||||
Users::WpJsonApi.new(target) <<
|
||||
Users::OembedApi.new(target) <<
|
||||
Users::RSSGenerator.new(target) <<
|
||||
Users::AuthorSitemap.new(target) <<
|
||||
Users::YoastSeoAuthorSitemap.new(target) <<
|
||||
Users::AuthorIdBruteForcing.new(target) <<
|
||||
Users::LoginErrorMessages.new(target)
|
||||
end
|
||||
|
||||
def finders
|
||||
@finders ||= Finders::UsersFinders.new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
36
app/finders/users/author_sitemap.rb
Normal file
36
app/finders/users/author_sitemap.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WPScan
|
||||
module Finders
|
||||
module Users
|
||||
# Since WP 5.5, /wp-sitemap-users-1.xml is generated and contains
|
||||
# the usernames of accounts who made a post
|
||||
class AuthorSitemap < CMSScanner::Finders::Finder
|
||||
# @param [ Hash ] opts
|
||||
#
|
||||
# @return [ Array<User> ]
|
||||
def aggressive(_opts = {})
|
||||
found = []
|
||||
|
||||
Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag|
|
||||
username = user_tag.text.to_s[%r{/author/([^/]+)/}, 1]
|
||||
|
||||
next unless username && !username.strip.empty?
|
||||
|
||||
found << Model::User.new(username,
|
||||
found_by: found_by,
|
||||
confidence: 100,
|
||||
interesting_entries: [sitemap_url])
|
||||
end
|
||||
|
||||
found
|
||||
end
|
||||
|
||||
# @return [ String ] The URL of the sitemap
|
||||
def sitemap_url
|
||||
@sitemap_url ||= target.url('wp-sitemap-users-1.xml')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -37,7 +37,7 @@ module WPScan
|
||||
# usernames from the potential Users found
|
||||
unames = opts[:found].map(&:username)
|
||||
|
||||
[*opts[:list]].each { |uname| unames << uname.chomp }
|
||||
Array(opts[:list]).each { |uname| unames << uname.chomp }
|
||||
|
||||
unames.uniq
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module WPScan
|
||||
urls.each do |url|
|
||||
res = Browser.get_and_follow_location(url)
|
||||
|
||||
next unless res.code == 200 && res.body =~ /<dc\:creator>/i
|
||||
next unless res.code == 200 && res.body =~ /<dc:creator>/i
|
||||
|
||||
potential_usernames = []
|
||||
|
||||
|
||||
@@ -5,27 +5,7 @@ module WPScan
|
||||
module Users
|
||||
# The YOAST SEO plugin has an author-sitemap.xml which can leak usernames
|
||||
# See https://github.com/wpscanteam/wpscan/issues/1228
|
||||
class YoastSeoAuthorSitemap < CMSScanner::Finders::Finder
|
||||
# @param [ Hash ] opts
|
||||
#
|
||||
# @return [ Array<User> ]
|
||||
def aggressive(_opts = {})
|
||||
found = []
|
||||
|
||||
Browser.get(sitemap_url).html.xpath('//url/loc').each do |user_tag|
|
||||
username = user_tag.text.to_s[%r{/author/([^\/]+)/}, 1]
|
||||
|
||||
next unless username && !username.strip.empty?
|
||||
|
||||
found << Model::User.new(username,
|
||||
found_by: found_by,
|
||||
confidence: 100,
|
||||
interesting_entries: [sitemap_url])
|
||||
end
|
||||
|
||||
found
|
||||
end
|
||||
|
||||
class YoastSeoAuthorSitemap < AuthorSitemap
|
||||
# @return [ String ] The URL of the author-sitemap
|
||||
def sitemap_url
|
||||
@sitemap_url ||= target.url('author-sitemap.xml')
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
# @param [ Boolean ] uniq Wether or not to apply the #uniq on the results
|
||||
#
|
||||
# @return [ Array<String> ] The plugins/themes detected in the href, src attributes of the page
|
||||
def items_from_links(type, uniq = true)
|
||||
def items_from_links(type, uniq: true)
|
||||
found = []
|
||||
xpath = format(
|
||||
'(//@href|//@src|//@data-src)[contains(., "%s")]',
|
||||
@@ -31,7 +31,7 @@ module WPScan
|
||||
# @param [ Boolean ] uniq Wether or not to apply the #uniq on the results
|
||||
#
|
||||
# @return [Array<String> ] The plugins/themes detected in the javascript/style of the homepage
|
||||
def items_from_codes(type, uniq = true)
|
||||
def items_from_codes(type, uniq: true)
|
||||
found = []
|
||||
|
||||
page_res.html.xpath('//script[not(@src)]|//style[not(@src)]').each do |tag|
|
||||
@@ -55,7 +55,7 @@ module WPScan
|
||||
#
|
||||
# @return [ Regexp ]
|
||||
def item_code_pattern(type)
|
||||
@item_code_pattern ||= %r{["'\( ]#{item_url_pattern(type)}([^\\\/\)"']+)}i
|
||||
@item_code_pattern ||= %r{["'( ]#{item_url_pattern(type)}([^\\/)"']+)}i
|
||||
end
|
||||
|
||||
# @param [ String ] type
|
||||
@@ -66,9 +66,9 @@ module WPScan
|
||||
item_url = type == 'plugins' ? target.plugins_url : target.content_url
|
||||
|
||||
url = /#{item_url.gsub(/\A(?:https?)/i, 'https?').gsub('/', '\\\\\?\/')}/i
|
||||
item_dir = %r{(?:#{url}|\\?\/#{item_dir.gsub('/', '\\\\\?\/')}\\?/)}i
|
||||
item_dir = %r{(?:#{url}|\\?/#{item_dir.gsub('/', '\\\\\?\/')}\\?/)}i
|
||||
|
||||
type == 'plugins' ? item_dir : %r{#{item_dir}#{type}\\?\/}i
|
||||
type == 'plugins' ? item_dir : %r{#{item_dir}#{type}\\?/}i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ module WPScan
|
||||
module Finders
|
||||
# Specific Finders container to filter the version detected
|
||||
# and remove the one with low confidence to avoid false
|
||||
# positive when there is not enought information to accurately
|
||||
# positive when there is not enough information to accurately
|
||||
# determine it.
|
||||
class WpVersionFinders < UniqueFinders
|
||||
def filter_findings
|
||||
|
||||
@@ -7,10 +7,11 @@ module WPScan
|
||||
include References
|
||||
end
|
||||
|
||||
#
|
||||
# Some classes are empty for the #type to be correctly displayed (as taken from the self.class from the parent)
|
||||
#
|
||||
class BackupDB < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "A backup directory has been found: #{url}"
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def references
|
||||
@references ||= { url: ['https://github.com/wpscanteam/wpscan/issues/422'] }
|
||||
@@ -18,6 +19,10 @@ module WPScan
|
||||
end
|
||||
|
||||
class DebugLog < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "Debug Log found: #{url}"
|
||||
end
|
||||
|
||||
# @ return [ Hash ]
|
||||
def references
|
||||
@references ||= { url: ['https://codex.wordpress.org/Debugging_in_WordPress'] }
|
||||
@@ -40,6 +45,10 @@ module WPScan
|
||||
end
|
||||
|
||||
class FullPathDisclosure < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "Full Path Disclosure found: #{url}"
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def references
|
||||
@references ||= { url: ['https://www.owasp.org/index.php/Full_Path_Disclosure'] }
|
||||
@@ -71,6 +80,9 @@ module WPScan
|
||||
end
|
||||
|
||||
class Readme < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "WordPress readme found: #{url}"
|
||||
end
|
||||
end
|
||||
|
||||
class Registration < InterestingFinding
|
||||
@@ -81,6 +93,10 @@ module WPScan
|
||||
end
|
||||
|
||||
class TmmDbMigrate < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "ThemeMakers migration file found: #{url}"
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def references
|
||||
@references ||= { packetstorm: [131_957] }
|
||||
@@ -95,6 +111,9 @@ module WPScan
|
||||
end
|
||||
|
||||
class UploadSQLDump < InterestingFinding
|
||||
def to_s
|
||||
@to_s ||= "SQL Dump found: #{url}"
|
||||
end
|
||||
end
|
||||
|
||||
class WPCron < InterestingFinding
|
||||
@@ -113,5 +132,19 @@ module WPScan
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
class PHPDisabled < InterestingFinding
|
||||
# @return [ String ]
|
||||
def to_s
|
||||
@to_s ||= 'PHP seems to be disabled'
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def references
|
||||
@references ||= {
|
||||
url: ['https://github.com/wpscanteam/wpscan/issues/1593']
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ module WPScan
|
||||
|
||||
# @return [ Array<String> ]
|
||||
def potential_readme_filenames
|
||||
@potential_readme_filenames ||= [*(DB::DynamicFinders::Plugin.df_data.dig(slug, 'Readme', 'path') || super)]
|
||||
@potential_readme_filenames ||= Array((DB::DynamicFinders::Plugin.df_data.dig(slug, 'Readme', 'path') || super))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,7 +45,7 @@ module WPScan
|
||||
# @return [ Theme ]
|
||||
def parent_theme
|
||||
return unless template
|
||||
return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i
|
||||
return unless style_body =~ /^@import\surl\(["']?([^"')]+)["']?\);\s*$/i
|
||||
|
||||
opts = detection_opts.merge(
|
||||
style_url: url(Regexp.last_match[1]),
|
||||
@@ -92,7 +92,7 @@ module WPScan
|
||||
tags: 'Tags',
|
||||
text_domain: 'Text Domain'
|
||||
}.each do |attribute, tag|
|
||||
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
|
||||
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag)&.force_encoding('UTF-8'))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -101,7 +101,7 @@ module WPScan
|
||||
#
|
||||
# @return [ String ]
|
||||
def parse_style_tag(body, tag)
|
||||
value = body[/#{Regexp.escape(tag)}:[\t ]*([^\r\n\*]+)/i, 1]
|
||||
value = body[/\b#{Regexp.escape(tag)}:[\t ]*([^\r\n*]+)/, 1]
|
||||
|
||||
value && !value.strip.empty? ? value.strip : nil
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ module WPScan
|
||||
def vulnerabilities
|
||||
vulns = []
|
||||
|
||||
vulns << rce_webshot_vuln if version == false || version > '1.35' && version < '2.8.14' && webshot_enabled?
|
||||
vulns << rce_webshot_vuln if version == false || (version > '1.35' && version < '2.8.14' && webshot_enabled?)
|
||||
vulns << rce_132_vuln if version == false || version < '1.33'
|
||||
|
||||
vulns
|
||||
@@ -63,7 +63,7 @@ module WPScan
|
||||
def webshot_enabled?
|
||||
res = Browser.get(url, params: { webshot: 1, src: "http://#{default_allowed_domains.sample}" })
|
||||
|
||||
/WEBSHOT_ENABLED == true/.match?(res.body) ? false : true
|
||||
!/WEBSHOT_ENABLED == true/.match?(res.body)
|
||||
end
|
||||
|
||||
# @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
|
||||
|
||||
@@ -39,7 +39,7 @@ module WPScan
|
||||
|
||||
@vulnerabilities = []
|
||||
|
||||
[*db_data['vulnerabilities']].each do |json_vuln|
|
||||
Array(db_data['vulnerabilities']).each do |json_vuln|
|
||||
vulnerability = Vulnerability.load_from_json(json_vuln)
|
||||
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
||||
end
|
||||
@@ -53,7 +53,9 @@ module WPScan
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def vulnerable_to?(vuln)
|
||||
return true unless version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
|
||||
return false if version && vuln&.introduced_in && version < vuln.introduced_in
|
||||
|
||||
return true unless version && vuln&.fixed_in && !vuln.fixed_in.empty?
|
||||
|
||||
version < vuln.fixed_in
|
||||
end
|
||||
@@ -160,7 +162,7 @@ module WPScan
|
||||
#
|
||||
# @return [ Typhoeus::Response ]
|
||||
def head_and_get(path, codes = [200], params = {})
|
||||
final_path = +@path_from_blog
|
||||
final_path = @path_from_blog.dup # @path_from_blog is set in the plugin/theme
|
||||
final_path << path unless path.nil?
|
||||
|
||||
blog.head_and_get(final_path, codes, params)
|
||||
|
||||
@@ -53,7 +53,7 @@ module WPScan
|
||||
|
||||
@vulnerabilities = []
|
||||
|
||||
[*db_data['vulnerabilities']].each do |json_vuln|
|
||||
Array(db_data['vulnerabilities']).each do |json_vuln|
|
||||
@vulnerabilities << Vulnerability.load_from_json(json_vuln)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<% unless @status.empty? -%>
|
||||
<% if @status['http_error'] -%>
|
||||
<%= critical_icon %> WPVulnDB API, <%= @status['http_error'].to_s %>
|
||||
<%= critical_icon %> WPScan DB API, <%= @status['http_error'].to_s %>
|
||||
<% else -%>
|
||||
<%= info_icon %> WPVulnDB API OK
|
||||
<%= info_icon %> WPScan DB 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/users/sign_up
|
||||
<%= warning_icon %> No WPScan API Token given, as a result vulnerability data has not been output.
|
||||
<%= warning_icon %> You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
|
||||
<% end -%>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<% if @version -%>
|
||||
<%= info_icon %> WordPress version <%= @version.number %> identified (<%= @version.status.capitalize %>, released on <%= @version.release_date %>).
|
||||
<%= info_icon %> WordPress version <%= @version.number %> identified (<%= @version.status.tr('-', '_').humanize %>, released on <%= @version.release_date %>).
|
||||
<%= render('@finding', item: @version) -%>
|
||||
<% else -%>
|
||||
<%= notice_icon %> The WordPress version could not be detected.
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"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/users/sign_up"
|
||||
"error": "No WPScan API Token given, as a result vulnerability data has not been output.\nYou can get a free API token with 25 daily requests by registering at https://wpscan.com/register"
|
||||
<% end -%>
|
||||
},
|
||||
@@ -13,6 +13,7 @@ require 'uri'
|
||||
require 'time'
|
||||
require 'readline'
|
||||
require 'securerandom'
|
||||
require 'resolv'
|
||||
# Monkey Patches/Fixes/Override
|
||||
require 'wpscan/typhoeus/response' # Adds a from_vuln_api? method
|
||||
# Custom Libs
|
||||
|
||||
@@ -7,7 +7,7 @@ module WPScan
|
||||
|
||||
# @return [ String ]
|
||||
def default_user_agent
|
||||
@default_user_agent ||= "WPScan v#{VERSION} (https://wpscan.org/)"
|
||||
@default_user_agent ||= "WPScan v#{VERSION} (https://wpscan.com/wordpress-security-scanner)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,11 @@ module WPScan
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.all_df_data
|
||||
@all_df_data ||= YAML.safe_load(File.read(df_file), [Regexp])
|
||||
@all_df_data ||= if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('4.0.0')
|
||||
YAML.safe_load(File.read(df_file), permitted_classes: [Regexp])
|
||||
else
|
||||
YAML.safe_load(File.read(df_file), [Regexp])
|
||||
end
|
||||
end
|
||||
|
||||
# @return [ Array<Symbol> ]
|
||||
@@ -31,7 +35,7 @@ module WPScan
|
||||
|
||||
finder_configs(
|
||||
finder_class,
|
||||
Regexp.last_match[1] == 'aggressive'
|
||||
aggressive: Regexp.last_match[1] == 'aggressive'
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ module WPScan
|
||||
# @param [ Symbol ] finder_class
|
||||
# @param [ Boolean ] aggressive
|
||||
# @return [ Hash ]
|
||||
def self.finder_configs(finder_class, aggressive = false)
|
||||
def self.finder_configs(finder_class, aggressive: false)
|
||||
configs = {}
|
||||
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
@@ -24,7 +24,7 @@ module WPScan
|
||||
# @param [ Symbol ] finder_class
|
||||
# @param [ Boolean ] aggressive
|
||||
# @return [ Hash ]
|
||||
def self.finder_configs(finder_class, aggressive = false)
|
||||
def self.finder_configs(finder_class, aggressive: false)
|
||||
configs = {}
|
||||
|
||||
return configs unless allowed_classes.include?(finder_class)
|
||||
|
||||
@@ -24,7 +24,13 @@ module WPScan
|
||||
|
||||
FileUtils.mkdir_p(repo_directory.to_s) unless Dir.exist?(repo_directory.to_s)
|
||||
|
||||
raise "#{repo_directory} is not writable" unless repo_directory.writable?
|
||||
# When --no-update is passed, return to avoid raising an error if the directory is not writable
|
||||
# Mainly there for Homebrew: https://github.com/wpscanteam/wpscan/pull/1455
|
||||
return if ParsedCli.update == false
|
||||
|
||||
unless repo_directory.writable?
|
||||
raise "#{repo_directory} is not writable (uid: #{Process.uid}, gid: #{Process.gid})"
|
||||
end
|
||||
|
||||
delete_old_files
|
||||
end
|
||||
@@ -67,7 +73,7 @@ module WPScan
|
||||
# @return [ Hash ] The params for Typhoeus::Request
|
||||
# @note Those params can't be overriden by CLI options
|
||||
def request_params
|
||||
@request_params ||= Browser.instance.default_connect_request_params.merge(
|
||||
@request_params ||= Browser.instance.default_request_params.merge(
|
||||
timeout: 600,
|
||||
connecttimeout: 300,
|
||||
accept_encoding: 'gzip, deflate',
|
||||
@@ -129,7 +135,7 @@ module WPScan
|
||||
res = Typhoeus.get(file_url, request_params)
|
||||
raise Error::Download, res if res.timed_out? || res.code != 200
|
||||
|
||||
File.open(file_path, 'wb') { |f| f.write(res.body) }
|
||||
File.binwrite(file_path, res.body)
|
||||
|
||||
local_file_checksum(filename)
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ module WPScan
|
||||
module DB
|
||||
# WPVulnDB API
|
||||
class VulnApi
|
||||
NON_ERROR_CODES = [200, 401].freeze
|
||||
NON_ERROR_CODES = [200, 403].freeze
|
||||
|
||||
class << self
|
||||
attr_accessor :token
|
||||
@@ -12,7 +12,7 @@ module WPScan
|
||||
|
||||
# @return [ Addressable::URI ]
|
||||
def self.uri
|
||||
@uri ||= Addressable::URI.parse('https://wpvulndb.com/api/v3/')
|
||||
@uri ||= Addressable::URI.parse('https://wpscan.com/api/v3/')
|
||||
end
|
||||
|
||||
# @param [ String ] path
|
||||
@@ -26,7 +26,7 @@ module WPScan
|
||||
# Typhoeus.get is used rather than Browser.get to avoid merging irrelevant params from the CLI
|
||||
res = Typhoeus.get(uri.join(path), default_request_params.merge(params))
|
||||
|
||||
return {} if res.code == 404 # This is for API inconsistencies when dots in path
|
||||
return {} if res.code == 404 || res.code == 429
|
||||
return JSON.parse(res.body) if NON_ERROR_CODES.include?(res.code)
|
||||
|
||||
raise Error::HTTP, res
|
||||
@@ -34,6 +34,8 @@ module WPScan
|
||||
retries ||= 0
|
||||
|
||||
if (retries += 1) <= 3
|
||||
@default_request_params[:headers]['X-Retry'] = retries
|
||||
|
||||
sleep(1)
|
||||
retry
|
||||
end
|
||||
@@ -68,7 +70,7 @@ module WPScan
|
||||
# @return [ Hash ]
|
||||
# @note Those params can not be overriden by CLI options
|
||||
def self.default_request_params
|
||||
Browser.instance.default_connect_request_params.merge(
|
||||
@default_request_params ||= Browser.instance.default_request_params.merge(
|
||||
headers: {
|
||||
'User-Agent' => Browser.instance.default_user_agent,
|
||||
'Authorization' => "Token token=#{token}"
|
||||
|
||||
@@ -5,16 +5,16 @@ module WPScan
|
||||
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.'
|
||||
'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.'
|
||||
'which might indicate False Positive. It would be recommended to use the --exclude-content-based ' \
|
||||
'option to ignore the bad responses.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,7 +26,13 @@ module WPScan
|
||||
class WpContentDirNotDetected < Standard
|
||||
def to_s
|
||||
'Unable to identify the wp-content dir, please supply it with --wp-content-dir,' \
|
||||
' use the --scope option or make sure the --url value given is the correct one'
|
||||
' use the --scope option or make sure the --url value given is the correct one'
|
||||
end
|
||||
end
|
||||
|
||||
class NoLoginInterfaceDetected < Standard
|
||||
def to_s
|
||||
'Could not find a login interface to perform the password attack against'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,8 +56,8 @@ module WPScan
|
||||
|
||||
homepage_result = find(target.homepage_res, opts)
|
||||
|
||||
if homepage_result
|
||||
return homepage_result unless homepage_result.is_a?(Array) && homepage_result.empty?
|
||||
unless homepage_result.nil? || (homepage_result.is_a?(Array) && homepage_result&.empty?)
|
||||
return homepage_result
|
||||
end
|
||||
|
||||
find(target.error_404_res, opts)
|
||||
|
||||
@@ -11,7 +11,7 @@ module WPScan
|
||||
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super.merge(
|
||||
PARSER: nil, KEY: nil, PATTERN: /(?<v>\d+\.[\.\d]+)/, CONFIDENCE: 70
|
||||
PARSER: nil, KEY: nil, PATTERN: /(?<v>\d+\.[.\d]+)/, CONFIDENCE: 70
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(
|
||||
XPATH: nil, FILES: nil, PATTERN: /(?:v|ver|version)\=(?<v>\d+\.[\.\d]+)/i, CONFIDENCE_PER_OCCURENCE: 10
|
||||
XPATH: nil, FILES: nil, PATTERN: /(?:v|ver|version)=(?<v>\d+\.[.\d]+)/i, CONFIDENCE_PER_OCCURENCE: 10
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ module WPScan
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(
|
||||
XPATH: nil, PATTERN: /\A(?<v>\d+\.[\.\d]+)/, CONFIDENCE: 60
|
||||
XPATH: nil, PATTERN: /\A(?<v>\d+\.[.\d]+)/, CONFIDENCE: 60
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ module WPScan
|
||||
|
||||
# @return [ Hash ]
|
||||
def self.child_class_constants
|
||||
@child_class_constants ||= super().merge(PATTERN: /ver\=(?<v>\d+\.[\.\d]+)/i)
|
||||
@child_class_constants ||= super().merge(PATTERN: /ver=(?<v>\d+\.[.\d]+)/i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -13,8 +13,11 @@ end
|
||||
#
|
||||
# @return [ Symbol ]
|
||||
def classify_slug(slug)
|
||||
classified = slug.to_s.gsub(/[^a-z\d\-]/i, '-').gsub(/\-{1,}/, '_').camelize.to_s
|
||||
classified = slug.to_s.gsub(/[^a-z\d\-]/i, '-').gsub(/-{1,}/, '_').camelize.to_s
|
||||
classified = "D_#{classified}" if /\d/.match?(classified[0])
|
||||
|
||||
# Special case for slugs with all non-latin characters.
|
||||
classified = "HexSlug_#{slug.bytes.map { |i| i.to_s(16) }.join}" if classified.empty?
|
||||
|
||||
classified.to_sym
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ module WPScan
|
||||
end
|
||||
|
||||
def wpvulndb_url(id)
|
||||
"https://wpvulndb.com/vulnerabilities/#{id}"
|
||||
"https://wpscan.com/vulnerability/#{id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,13 +19,13 @@ module WPScan
|
||||
# @return [ Boolean ]
|
||||
def vulnerable?
|
||||
[@wp_version, @main_theme, @plugins, @themes, @timthumbs].each do |e|
|
||||
[*e].each { |ae| return true if ae && ae.vulnerable? } # rubocop:disable Style/SafeNavigation
|
||||
Array(e).each { |ae| return true if ae && ae.vulnerable? } # rubocop:disable Style/SafeNavigation
|
||||
end
|
||||
|
||||
return true unless [*@config_backups].empty?
|
||||
return true unless [*@db_exports].empty?
|
||||
return true unless Array(@config_backups).empty?
|
||||
return true unless Array(@db_exports).empty?
|
||||
|
||||
[*@users].each { |u| return true if u.password }
|
||||
Array(@users).each { |u| return true if u.password }
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
@@ -11,9 +11,10 @@ module WPScan
|
||||
module WordPress
|
||||
include CMSScanner::Target::Platform::PHP
|
||||
|
||||
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu\-)?plugins|uploads))|wp-includes)/}i.freeze
|
||||
WP_JSON_OEMBED_PATTERN = %r{/wp\-json/oembed/}i.freeze
|
||||
WP_ADMIN_AJAX_PATTERN = %r{\\?/wp\-admin\\?/admin\-ajax\.php}i.freeze
|
||||
WORDPRESS_PATTERN = %r{/(?:(?:wp-content/(?:themes|(?:mu-)?plugins|uploads))|wp-includes)/}i.freeze
|
||||
WORDPRESS_HOSTED_PATTERN = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
|
||||
WP_JSON_OEMBED_PATTERN = %r{/wp-json/oembed/}i.freeze
|
||||
WP_ADMIN_AJAX_PATTERN = %r{\\?/wp-admin\\?/admin-ajax\.php}i.freeze
|
||||
|
||||
# These methods are used in the associated interesting_findings finders
|
||||
# to keep the boolean state of the finding rather than re-check the whole thing again
|
||||
@@ -103,11 +104,8 @@ module WPScan
|
||||
return true if /\.wordpress\.com$/i.match?(uri.host)
|
||||
|
||||
unless content_dir
|
||||
pattern = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
|
||||
xpath = '(//@href|//@src)[contains(., "wp.com")]'
|
||||
|
||||
uris_from_page(homepage_res, xpath) do |uri|
|
||||
return true if uri.to_s.match?(pattern)
|
||||
uris_from_page(homepage_res, '(//@href|//@src)[contains(., "wp.com")]') do |uri|
|
||||
return true if uri.to_s.match?(WORDPRESS_HOSTED_PATTERN)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -139,15 +137,19 @@ module WPScan
|
||||
# the first time the method is called, and the effective_url is then used
|
||||
# if suitable, otherwise the default wp-login will be.
|
||||
#
|
||||
# @return [ String ] The URL to the login page
|
||||
# If the login_uri CLI option has been provided, it will be returne w/o redirection check.
|
||||
#
|
||||
# @return [ String, false ] The URL to the login page or false if not detected
|
||||
def login_url
|
||||
return @login_url if @login_url
|
||||
return @login_url unless @login_url.nil?
|
||||
return @login_url = url(ParsedCli.login_uri) if ParsedCli.login_uri
|
||||
|
||||
@login_url = url('wp-login.php')
|
||||
|
||||
res = Browser.get_and_follow_location(@login_url)
|
||||
|
||||
@login_url = res.effective_url if res.effective_url =~ /wp\-login\.php\z/i && in_scope?(res.effective_url)
|
||||
@login_url = res.effective_url if res.effective_url =~ /wp-login\.php\z/i && in_scope?(res.effective_url)
|
||||
@login_url = false if res.code == 404
|
||||
|
||||
@login_url
|
||||
end
|
||||
|
||||
@@ -104,7 +104,7 @@ module WPScan
|
||||
return @sub_dir unless @sub_dir.nil?
|
||||
|
||||
# url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
|
||||
pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp-includes/)}i
|
||||
xpath = '(//@src|//@href|//@data-src)[contains(., "xmlrpc.php") or contains(., "wp-includes/")]'
|
||||
|
||||
[homepage_res, error_404_res].each do |page_res|
|
||||
@@ -124,15 +124,15 @@ module WPScan
|
||||
def url(path = nil)
|
||||
return @uri.to_s unless path
|
||||
|
||||
if %r{wp\-content/plugins}i.match?(path)
|
||||
path = +path.gsub('wp-content/plugins', plugins_dir)
|
||||
elsif /wp\-content/i.match?(path)
|
||||
path = +path.gsub('wp-content', content_dir)
|
||||
if %r{wp-content/plugins}i.match?(path)
|
||||
new_path = path.gsub('wp-content/plugins', plugins_dir)
|
||||
elsif /wp-content/i.match?(path)
|
||||
new_path = path.gsub('wp-content', content_dir)
|
||||
elsif path[0] != '/' && sub_dir
|
||||
path = "#{sub_dir}/#{path}"
|
||||
new_path = "#{sub_dir}/#{path}"
|
||||
end
|
||||
|
||||
super(path)
|
||||
super(new_path || path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,8 @@ module Typhoeus
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def from_vuln_api?
|
||||
effective_url.start_with?(WPScan::DB::VulnApi.uri.to_s) && !effective_url.include?('/status')
|
||||
effective_url.start_with?(WPScan::DB::VulnApi.uri.to_s) &&
|
||||
!effective_url.start_with?(WPScan::DB::VulnApi.uri.join('status').to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
# Version
|
||||
module WPScan
|
||||
VERSION = '3.8.2'
|
||||
VERSION = '3.8.25'
|
||||
end
|
||||
|
||||
@@ -21,6 +21,7 @@ module WPScan
|
||||
references: references,
|
||||
type: json_data['vuln_type'],
|
||||
fixed_in: json_data['fixed_in'],
|
||||
introduced_in: json_data['introduced_in'],
|
||||
cvss: json_data['cvss']&.symbolize_keys
|
||||
)
|
||||
end
|
||||
|
||||
@@ -52,9 +52,10 @@ describe WPScan::Controller::Core do
|
||||
%i[apache iis nginx].each do |server|
|
||||
context "when #{server}" do
|
||||
let(:cli_args) { "#{super()} --server #{server}" }
|
||||
let(:servers) { [:Apache, nil, :IIS, :Nginx] }
|
||||
|
||||
it "loads the #{server.capitalize} module and returns :#{server}" do
|
||||
@stubbed_server = [:Apache, nil, :IIS, :Nginx].sample
|
||||
@stubbed_server = servers.sample
|
||||
@expected = server == :iis ? :IIS : server.to_s.camelize.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
@@ -76,7 +76,7 @@ describe WPScan::Controller::Enumeration do
|
||||
config_backups_list config_backups_detection
|
||||
db_exports_list db_exports_detection
|
||||
medias_detection
|
||||
users_list users_detection]
|
||||
users_list users_detection exclude_usernames]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
XMLRPC_FAILED_BODY = '
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodResponse>
|
||||
<fault>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>faultCode</name>
|
||||
<value><int>405</int></value>
|
||||
</member>
|
||||
<member>
|
||||
<name>faultString</name>
|
||||
<value><string>%s</string></value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</fault>
|
||||
</methodResponse>'
|
||||
|
||||
describe WPScan::Controller::PasswordAttack do
|
||||
subject(:controller) { described_class.new }
|
||||
let(:target_url) { 'http://ex.lo/' }
|
||||
@@ -15,13 +34,13 @@ describe WPScan::Controller::PasswordAttack do
|
||||
|
||||
it 'contains to correct options' do
|
||||
expect(controller.cli_options.map(&:to_sym))
|
||||
.to eq(%i[passwords usernames multicall_max_passwords password_attack])
|
||||
.to eq(%i[passwords usernames multicall_max_passwords password_attack login_uri])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#users' do
|
||||
context 'when no --usernames' do
|
||||
it 'calles target.users' do
|
||||
it 'calls target.users' do
|
||||
expect(controller.target).to receive(:users)
|
||||
controller.users
|
||||
end
|
||||
@@ -40,10 +59,6 @@ describe WPScan::Controller::PasswordAttack do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#passwords' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#run' do
|
||||
context 'when no --passwords is supplied' do
|
||||
it 'does not run the attacker' do
|
||||
@@ -85,20 +100,34 @@ describe WPScan::Controller::PasswordAttack do
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method listed' do
|
||||
before { expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2]) }
|
||||
before do
|
||||
expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2])
|
||||
|
||||
stub_request(:post, xmlrpc.url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method disabled' do
|
||||
it 'returns false' do
|
||||
stub_request(:post, xmlrpc.url).to_return(body: 'XML-RPC services are disabled on this site.')
|
||||
context 'when blog is in EN' do
|
||||
let(:body) { format(XMLRPC_FAILED_BODY, 'XML-RPC services are disabled on this site.') }
|
||||
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
it 'returns false' do
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when blog is in FR' do
|
||||
let(:body) { format(XMLRPC_FAILED_BODY, 'Les services XML-RPC sont désactivés sur ce site.') }
|
||||
|
||||
it 'returns false' do
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wp.getUsersBlogs method enabled' do
|
||||
it 'returns true' do
|
||||
stub_request(:post, xmlrpc.url).to_return(body: 'Incorrect username or password.')
|
||||
let(:body) { 'Incorrect username or password.' }
|
||||
|
||||
it 'returns true' do
|
||||
expect(controller.xmlrpc_get_users_blogs_enabled?).to be true
|
||||
end
|
||||
end
|
||||
@@ -107,15 +136,34 @@ describe WPScan::Controller::PasswordAttack do
|
||||
end
|
||||
|
||||
describe '#attacker' do
|
||||
before do
|
||||
allow(controller.target).to receive(:sub_dir)
|
||||
controller.target.instance_variable_set(:@login_url, nil)
|
||||
end
|
||||
|
||||
context 'when --password-attack provided' do
|
||||
let(:cli_args) { "#{super()} --password-attack #{attack}" }
|
||||
|
||||
context 'when wp-login' do
|
||||
before { stub_request(:get, controller.target.url('wp-login.php')).to_return(status: status) }
|
||||
|
||||
let(:attack) { 'wp-login' }
|
||||
|
||||
it 'returns the correct object' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
context 'when available' do
|
||||
let(:status) { 200 }
|
||||
|
||||
it 'returns the correct object' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not available (404)' do
|
||||
let(:status) { 404 }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { controller.attacker }.to raise_error(WPScan::Error::NoLoginInterfaceDetected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -172,11 +220,26 @@ describe WPScan::Controller::PasswordAttack do
|
||||
|
||||
context 'when automatic detection' do
|
||||
context 'when xmlrpc_get_users_blogs_enabled? is false' do
|
||||
it 'returns the WpLogin' do
|
||||
before do
|
||||
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(false)
|
||||
stub_request(:get, controller.target.url('wp-login.php')).to_return(status: status)
|
||||
end
|
||||
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
context 'when wp-login available' do
|
||||
let(:status) { 200 }
|
||||
|
||||
it 'returns the WpLogin' do
|
||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||
expect(controller.attacker.target).to be_a WPScan::Target
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wp-login.php not available' do
|
||||
let(:status) { 404 }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { controller.attacker }.to raise_error(WPScan::Error::NoLoginInterfaceDetected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ describe WPScan::Controller::VulnApi do
|
||||
|
||||
before do
|
||||
WPScan::ParsedCli.options = rspec_parsed_options(cli_args)
|
||||
WPScan::DB::VulnApi.instance_variable_set(:@default_request_params, nil)
|
||||
end
|
||||
|
||||
describe '#cli_options' do
|
||||
@@ -27,7 +28,7 @@ describe WPScan::Controller::VulnApi 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.') }
|
||||
before { expect(WPScan::DB::VulnApi).to receive(:status).and_return('status' => 'forbidden') }
|
||||
|
||||
it 'raise an InvalidApiToken error' do
|
||||
expect { controller.before_scan }.to raise_error(WPScan::Error::InvalidApiToken)
|
||||
|
||||
@@ -12,7 +12,7 @@ describe WPScan::Finders::DbExports::KnownLocations do
|
||||
allow(target).to receive(:sub_dir).and_return(false)
|
||||
end
|
||||
|
||||
it 'replaces {domain_name} by its value' do
|
||||
it 'replaces {domain_name} by its values' do
|
||||
expect(finder.potential_urls(opts).keys).to eql %w[
|
||||
http://ex.lo/aa/ex.sql
|
||||
http://ex.lo/aa/wordpress.sql
|
||||
@@ -27,8 +27,8 @@ describe WPScan::Finders::DbExports::KnownLocations do
|
||||
context "when #{sub_domain} sub-domain" do
|
||||
let(:url) { "https://#{sub_domain}.domain.tld" }
|
||||
|
||||
it 'replaces {domain_name} by its correct value' do
|
||||
expect(finder.potential_urls(opts).keys).to include "#{url}/domain.sql"
|
||||
it 'replaces {domain_name} by its correct values' do
|
||||
expect(finder.potential_urls(opts).keys).to include "#{url}/domain.sql", "#{url}/#{sub_domain}.domain.sql"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -44,16 +44,22 @@ describe WPScan::Finders::DbExports::KnownLocations do
|
||||
context 'when multi-level tlds and sub-domain' do
|
||||
let(:url) { 'https://dev.something.com.tr' }
|
||||
|
||||
it 'replaces {domain_name} by its correct value' do
|
||||
expect(finder.potential_urls(opts).keys).to include 'https://dev.something.com.tr/something.sql'
|
||||
it 'replaces {domain_name} by its correct values' do
|
||||
expect(finder.potential_urls(opts).keys).to include(
|
||||
'https://dev.something.com.tr/something.sql',
|
||||
'https://dev.something.com.tr/dev.something.sql'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some weird stuff' do
|
||||
let(:url) { 'https://098f6bcd4621d373cade4e832627b4f6.aa-bb-ccc-dd.domain-test.com' }
|
||||
|
||||
it 'replaces {domain_name} by its correct value' do
|
||||
expect(finder.potential_urls(opts).keys).to include "#{url}/domain-test.sql"
|
||||
it 'replaces {domain_name} by its correct values' do
|
||||
expect(finder.potential_urls(opts).keys).to include(
|
||||
"#{url}/domain-test.sql",
|
||||
"#{url}/098f6bcd4621d373cade4e832627b4f6.aa-bb-ccc-dd.domain-test.sql"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,6 +70,14 @@ describe WPScan::Finders::DbExports::KnownLocations do
|
||||
expect(finder.potential_urls(opts).keys).to include "#{url}/dc-2.sql"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an IP address' do
|
||||
let(:url) { 'http://192.168.1.12' }
|
||||
|
||||
it 'replaces {domain_name} by the IP address' do
|
||||
expect(finder.potential_urls(opts).keys).to include "#{url}/192.168.1.12.sql"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
@@ -102,19 +116,29 @@ describe WPScan::Finders::DbExports::KnownLocations do
|
||||
expect(target).to receive(:homepage_or_404?).twice.and_return(false)
|
||||
end
|
||||
|
||||
it 'returns the expected Array<DbExport>' do
|
||||
expected = []
|
||||
context 'when matching the pattern' do
|
||||
it 'returns the expected Array<DbExport>' do
|
||||
expected = []
|
||||
|
||||
found_files.each do |file|
|
||||
url = "#{target.url}#{file}"
|
||||
expected << WPScan::Model::DbExport.new(
|
||||
url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
found_files.each do |file|
|
||||
url = "#{target.url}#{file}"
|
||||
expected << WPScan::Model::DbExport.new(
|
||||
url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
|
||||
expect(finder.aggressive(opts)).to eql expected
|
||||
end
|
||||
end
|
||||
|
||||
expect(finder.aggressive(opts)).to eql expected
|
||||
context 'when not matching the pattern' do
|
||||
let(:db_export) { '' }
|
||||
|
||||
it 'returns an empty array' do
|
||||
expect(finder.aggressive(opts)).to eql []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,15 +35,47 @@ describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do
|
||||
end
|
||||
|
||||
context 'when the body matches' do
|
||||
let(:body) { File.read(fixtures.join(filename)) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
after do
|
||||
expect(finder.aggressive).to eql WPScan::Model::DuplicatorInstallerLog.new(
|
||||
log_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
|
||||
context 'when old versions of the file' do
|
||||
let(:body) { File.read(fixtures.join('old.txt')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
# handled in after loop above
|
||||
end
|
||||
end
|
||||
|
||||
context 'when newest versions of the file' do
|
||||
context 'when PRO format 1' do
|
||||
let(:body) { File.read(fixtures.join('pro.txt')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
# handled in after loop above
|
||||
end
|
||||
end
|
||||
|
||||
context 'when PRO format 2' do
|
||||
let(:body) { File.read(fixtures.join('pro2.txt')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
# handled in after loop above
|
||||
end
|
||||
end
|
||||
|
||||
context 'when LITE' do
|
||||
let(:body) { File.read(fixtures.join('lite.txt')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
# handled in after loop above
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ describe WPScan::Finders::InterestingFindings::EmergencyPwdResetScript do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:file_url) { url + 'emergency.php' }
|
||||
let(:file_url) { "#{url}emergency.php" }
|
||||
let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'emergency_pwd_reset_script') }
|
||||
|
||||
before do
|
||||
|
||||
50
spec/app/finders/interesting_findings/php_disabled_spec.rb
Normal file
50
spec/app/finders/interesting_findings/php_disabled_spec.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::PHPDisabled do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'php_disabled') }
|
||||
let(:file_path) { 'wp-includes/version.php' }
|
||||
let(:file_url) { target.url(file_path) }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
expect(target).to receive(:head_or_get_params).and_return(method: :head)
|
||||
end
|
||||
|
||||
context 'when not a 200' do
|
||||
it 'return nil' do
|
||||
stub_request(:head, file_url).to_return(status: 404)
|
||||
|
||||
expect(finder.aggressive).to eql nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a 200' do
|
||||
before do
|
||||
stub_request(:head, file_url)
|
||||
stub_request(:get, file_url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when the body does not match' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when the body matches' do
|
||||
let(:body) { File.read(fixtures.join('version.php')) }
|
||||
|
||||
it 'returns the PHPDisabled' do
|
||||
expect(finder.aggressive).to eql WPScan::Model::PHPDisabled.new(
|
||||
file_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,7 +4,7 @@ describe WPScan::Finders::InterestingFindings::UploadSQLDump do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:dump_url) { url + 'wp-content/uploads/dump.sql' }
|
||||
let(:dump_url) { "#{url}wp-content/uploads/dump.sql" }
|
||||
let(:fixtures) { FINDERS_FIXTURES.join('interesting_findings', 'upload_sql_dump') }
|
||||
let(:wp_content) { 'wp-content' }
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ describe WPScan::Finders::InterestingFindings::Base do
|
||||
%w[
|
||||
Readme DebugLog FullPathDisclosure
|
||||
Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate
|
||||
UploadSQLDump
|
||||
UploadSQLDump PHPDisabled
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ describe WPScan::Finders::Medias::AttachmentBruteForcing do
|
||||
describe '#target_urls' do
|
||||
it 'returns the expected urls' do
|
||||
expect(finder.target_urls(range: (1..2))).to eql(
|
||||
url + '?attachment_id=1' => 1,
|
||||
url + '?attachment_id=2' => 2
|
||||
"#{url}?attachment_id=1" => 1,
|
||||
"#{url}?attachment_id=2" => 2
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,7 +35,7 @@ describe WPScan::Finders::Passwords::WpLogin do
|
||||
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=/'
|
||||
'Set-Cookie: something=value; path=/'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
@@ -47,9 +47,9 @@ describe WPScan::Finders::Passwords::WpLogin do
|
||||
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'
|
||||
"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
|
||||
|
||||
@@ -24,11 +24,13 @@ describe WPScan::Finders::Passwords::XMLRPC do
|
||||
</methodResponse>'
|
||||
|
||||
describe '#attack' do
|
||||
let(:wordlist_path) { FINDERS_FIXTURES.join('passwords.txt').to_s }
|
||||
|
||||
context 'when no valid credentials' do
|
||||
before do
|
||||
stub_request(:post, url).to_return(status: status, body: RESPONSE_403_BODY)
|
||||
|
||||
finder.attack(users, %w[pwd])
|
||||
finder.attack(users, wordlist_path)
|
||||
end
|
||||
|
||||
let(:users) { %w[admin].map { |username| WPScan::Model::User.new(username) } }
|
||||
|
||||
@@ -108,7 +108,8 @@ describe WPScan::Finders::PluginVersion::Readme do
|
||||
'advanced-most-recent-posts-mod' => '1.6.5.2',
|
||||
'a-lead-capture-contact-form-and-tab-button-by-awebvoicecom' => '3.1',
|
||||
'backup-scheduler' => '1.5.9',
|
||||
'release_date_slash' => '1.0.4'
|
||||
'release_date_slash' => '1.0.4',
|
||||
'cool_tag_cloud' => '2.27'
|
||||
}.each do |file, version_number|
|
||||
context "whith #{file}.txt" do
|
||||
it 'returns the expected version' do
|
||||
|
||||
@@ -13,8 +13,8 @@ describe WPScan::Finders::Users::AuthorIdBruteForcing do
|
||||
describe '#target_urls' do
|
||||
it 'returns the correct URLs' do
|
||||
expect(finder.target_urls(range: (1..2))).to eql(
|
||||
url + '?author=1' => 1,
|
||||
url + '?author=2' => 2
|
||||
"#{url}?author=1" => 1,
|
||||
"#{url}?author=2" => 2
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
48
spec/app/finders/users/author_sitemap_spec.rb
Normal file
48
spec/app/finders/users/author_sitemap_spec.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe WPScan::Finders::Users::AuthorSitemap do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { FINDERS_FIXTURES.join('users', 'author_sitemap') }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
allow(target).to receive(:sub_dir).and_return(false)
|
||||
|
||||
stub_request(:get, finder.sitemap_url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when not an XML response' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should eql([]) }
|
||||
end
|
||||
|
||||
context 'when an XML response' do
|
||||
context 'when no usernames disclosed' do
|
||||
let(:body) { File.read(fixtures.join('no_usernames.xml')) }
|
||||
|
||||
its(:aggressive) { should eql([]) }
|
||||
end
|
||||
|
||||
context 'when usernames disclosed' do
|
||||
let(:body) { File.read(fixtures.join('usernames.xml')) }
|
||||
|
||||
it 'returns the expected array of users' do
|
||||
users = finder.aggressive
|
||||
|
||||
expect(users.size).to eql 2
|
||||
|
||||
expect(users.first.username).to eql 'admin'
|
||||
expect(users.first.confidence).to eql 100
|
||||
expect(users.first.interesting_entries).to eql ['http://wp.lab/wp-sitemap-users-1.xml']
|
||||
|
||||
expect(users.last.username).to eql 'author'
|
||||
expect(users.last.confidence).to eql 100
|
||||
expect(users.last.interesting_entries).to eql ['http://wp.lab/wp-sitemap-users-1.xml']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,7 +8,7 @@ describe WPScan::Finders::Users::Base do
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(user.finders.map { |f| f.class.to_s.demodulize })
|
||||
.to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator YoastSeoAuthorSitemap
|
||||
.to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator AuthorSitemap YoastSeoAuthorSitemap
|
||||
AuthorIdBruteForcing LoginErrorMessages]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ describe WPScan::Finders::WpVersion::Readme do
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { FINDERS_FIXTURES.join('wp_version', 'readme') }
|
||||
let(:readme_url) { url + 'readme.html' }
|
||||
let(:readme_url) { "#{url}readme.html" }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { stub_request(:get, readme_url).to_return(body: File.read(fixtures.join(file))) }
|
||||
|
||||
@@ -172,7 +172,7 @@ describe WPScan::Model::Plugin do
|
||||
|
||||
after do
|
||||
expect(plugin.vulnerabilities).to eq @expected
|
||||
expect(plugin.vulnerable?).to eql @expected.empty? ? false : true
|
||||
expect(plugin.vulnerable?).to eql !@expected.empty?
|
||||
end
|
||||
|
||||
context 'when plugin not in the DB' do
|
||||
@@ -195,50 +195,108 @@ describe WPScan::Model::Plugin do
|
||||
end
|
||||
|
||||
context 'when vulnerabilities' do
|
||||
let(:slug) { 'vulnerable-not-popular' }
|
||||
let(:db_data) { vuln_api_data_for('plugins/vulnerable-not-popular') }
|
||||
context 'when only fixed_in' do
|
||||
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 <= 6.3.10 - LFI',
|
||||
references: { wpvulndb: '1' },
|
||||
type: 'LFI',
|
||||
fixed_in: '6.3.10'
|
||||
),
|
||||
WPScan::Vulnerability.new('No Fixed In', references: { wpvulndb: '2' })
|
||||
]
|
||||
end
|
||||
|
||||
context 'when no plugin version' do
|
||||
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
|
||||
|
||||
it 'returns all the vulnerabilities' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when plugin version' do
|
||||
before do
|
||||
expect(plugin)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new(number))
|
||||
let(:all_vulns) do
|
||||
[
|
||||
WPScan::Vulnerability.new(
|
||||
'First Vuln <= 6.3.10 - LFI',
|
||||
references: { wpvulndb: '1' },
|
||||
type: 'LFI',
|
||||
fixed_in: '6.3.10'
|
||||
),
|
||||
WPScan::Vulnerability.new('No Fixed In', references: { wpvulndb: '2' })
|
||||
]
|
||||
end
|
||||
|
||||
context 'when < to a fixed_in' do
|
||||
let(:number) { '5.0' }
|
||||
context 'when no plugin version' do
|
||||
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
|
||||
|
||||
it 'returns it' do
|
||||
it 'returns all the vulnerabilities' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when >= to a fixed_in' do
|
||||
let(:number) { '6.3.10' }
|
||||
context 'when plugin version' do
|
||||
before do
|
||||
expect(plugin)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new(number))
|
||||
end
|
||||
|
||||
it 'does not return it ' do
|
||||
@expected = [all_vulns.last]
|
||||
context 'when < to fixed_in' do
|
||||
let(:number) { '5.0' }
|
||||
|
||||
it 'returns it' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when >= to fixed_in' do
|
||||
let(:number) { '6.3.10' }
|
||||
|
||||
it 'does not return it ' do
|
||||
@expected = [all_vulns.last]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when introduced_in' do
|
||||
let(:db_data) { vuln_api_data_for('plugins/vulnerable-introduced-in') }
|
||||
|
||||
let(:all_vulns) do
|
||||
[
|
||||
WPScan::Vulnerability.new(
|
||||
'Introduced In 6.4',
|
||||
fixed_in: '6.5',
|
||||
introduced_in: '6.4',
|
||||
references: { wpvulndb: '1' }
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
context 'when no plugin version' do
|
||||
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
|
||||
|
||||
it 'returns all the vulnerabilities' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
|
||||
context 'when plugin version' do
|
||||
before do
|
||||
expect(plugin)
|
||||
.to receive(:version)
|
||||
.at_least(1)
|
||||
.and_return(WPScan::Model::Version.new(number))
|
||||
end
|
||||
|
||||
context 'when < to introduced_in' do
|
||||
let(:number) { '5.0' }
|
||||
|
||||
it 'does not return it' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when >= to fixed_in' do
|
||||
let(:number) { '6.5' }
|
||||
|
||||
it 'does not return it' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when >= to introduced_in' do
|
||||
let(:number) { '6.4' }
|
||||
|
||||
it 'returns it' do
|
||||
@expected = all_vulns
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,6 +41,12 @@ describe WPScan::Model::Theme do
|
||||
its(:style_uri) { should eql 'http://www.elegantthemes.com/gallery/divi/' }
|
||||
its(:license_uri) { should eql 'http://www.gnu.org/licenses/gpl-2.0.html' }
|
||||
end
|
||||
|
||||
context 'when no tags' do
|
||||
let(:fixture) { fixtures.join('no_tags.css') }
|
||||
|
||||
its(:author) { should eql nil }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#version' do
|
||||
@@ -194,7 +200,7 @@ describe WPScan::Model::Theme do
|
||||
|
||||
after do
|
||||
expect(theme.vulnerabilities).to eq @expected
|
||||
expect(theme.vulnerable?).to eql @expected.empty? ? false : true
|
||||
expect(theme.vulnerable?).to eql !@expected.empty?
|
||||
end
|
||||
|
||||
context 'when theme not in the DB' do
|
||||
|
||||
53268
spec/fixtures/db/dynamic_finders.yml
vendored
53268
spec/fixtures/db/dynamic_finders.yml
vendored
File diff suppressed because it is too large
Load Diff
13
spec/fixtures/db/vuln_api/plugins/vulnerable-introduced-in.json
vendored
Normal file
13
spec/fixtures/db/vuln_api/plugins/vulnerable-introduced-in.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"latest_version": null,
|
||||
"last_updated": null,
|
||||
"popular": false,
|
||||
"vulnerabilities" : [
|
||||
{
|
||||
"title": "Introduced In 6.4",
|
||||
"id": 1,
|
||||
"introduced_in": "6.4",
|
||||
"fixed_in": "6.5"
|
||||
}
|
||||
]
|
||||
}
|
||||
22507
spec/fixtures/dynamic_finders/expected.yml
vendored
22507
spec/fixtures/dynamic_finders/expected.yml
vendored
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
= 4.0.0 =
|
||||
* Released 2021.07.20
|
||||
* Upgraded to use V4 of the what3words AutoSuggest Component with improved styling and functionality.
|
||||
* Updated admin section interface.
|
||||
* Addition of advanced clipping options to restrict suggestions displayed to a user.
|
||||
* Addition of options to store latitude and longitude coordinates and nearest place against a record.
|
||||
* Added ability to change the field label.
|
||||
|
||||
= 3.0.11 =
|
||||
* Released 2021.06.30
|
||||
* Fixes non-fatal debugging log output for PHP "Variable assignment" error
|
||||
|
||||
= 3.0.10 =
|
||||
* Released 2021.03.09
|
||||
* Fixes passing API key to autosuggest for requests.
|
||||
|
||||
= 3.0.9 =
|
||||
* Released 2021.02.03
|
||||
* Updated screenshots
|
||||
* Send key version numbers to what3words API via `X-W3W-Plugin` request header.
|
||||
|
||||
= 3.0.8 =
|
||||
* Released 2020.12.11
|
||||
* Improved interoperability, errors in 3rd party scripts will be less likely to prevent the plugin operating.
|
||||
* Bumped to latest WordPress release, 5.6
|
||||
|
||||
= 3.0.7 =
|
||||
* Released 2020.06.17
|
||||
* Addresses an error that prevented the plugin loading on Internet Explorer.
|
||||
* Minor styling improvements.
|
||||
|
||||
= 3.0.6 =
|
||||
* Released 2020.06.02
|
||||
* Further improvements to match theme styling
|
||||
* Clarified the purpose of the `Input Selector(s)` field
|
||||
* Updated readme
|
||||
|
||||
= 3.0.5 =
|
||||
* Released 2020.06.01
|
||||
* Apply missing `font-size` property.
|
||||
|
||||
= 3.0.4 =
|
||||
* Released 2020.06.01
|
||||
* Hotfix missing `font-size` property.
|
||||
|
||||
= 3.0.3 =
|
||||
* Released 2020.06.01
|
||||
* Plugin tweaked to take up less vertical height on themes with slimmer text inputs.
|
||||
|
||||
= 3.0.2 =
|
||||
* Released 2020.06.01
|
||||
* The plugin now inherits styles from the current wordpress theme for more seamless integration.
|
||||
* The following css properties are automatically applied to the upgraded input: `background-color`, `border`, `border-radius`, `color`, `font`, `height`.
|
||||
|
||||
= 3.0.1 =
|
||||
* Released 2020.05.27
|
||||
* Fixes an issue where country clipping would not work when shipping and billing addresses were in different countries.
|
||||
* Updated screenshots
|
||||
|
||||
= 3.0.0 =
|
||||
* Released 2020.05.26
|
||||
* Updated the plugin to use new web component and V3 of the what3words API. Note that this release simplifies the plugin setup and removes some settings.
|
||||
* Updated links to what3words documentation and developer site
|
||||
* Settings available are now:
|
||||
* API key
|
||||
* CSS selector to specify which inputs should be upgraded to the auto suggest component
|
||||
* Placeholder text shown on inputs
|
||||
* Turn on/off the WooCommerce integration, to automatically add what3words address fields to your checkout forms
|
||||
|
||||
= 2.0.4 =
|
||||
* Released 2019.01.16
|
||||
* Added new function to allow a country field to be specified for country clipping
|
||||
|
||||
= 2.0.3 =
|
||||
* Released 2018.04.05
|
||||
* bug fixes
|
||||
|
||||
= 2.0.2 =
|
||||
* Released 2018.03.16
|
||||
* bug fixes
|
||||
|
||||
= 2.0.1 =
|
||||
* Released 2018.01.09
|
||||
* bug fixes
|
||||
|
||||
= 2.0.0 =
|
||||
* Released 2018.01.08
|
||||
* Reworked and redesigned plugin code base
|
||||
|
||||
= 1.1.0 =
|
||||
* uses what3words autosuggest jQuery plugin 1.2.0
|
||||
|
||||
= 1.0.1 =
|
||||
* General fixes
|
||||
|
||||
= 1.0.0 =
|
||||
* Initial release
|
||||
@@ -0,0 +1,170 @@
|
||||
# Copyright (C) 2023 Qewebby
|
||||
# This file is distributed under the GPL-2.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 360 Product Viewer for WooCommerce 1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp_360view\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: 2023-05-11T17:47:24+05:30\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.7.1\n"
|
||||
"X-Domain: wp360view\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
#. Description of the plugin
|
||||
msgid "360 Product Viewer for WooCommerce"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://wordpress.org/plugins/360-product-viewer-for-woocommerce/"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Qewebby"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://www.qewebby.com"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:108
|
||||
msgid "360 Product image"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:141
|
||||
msgid "Delete image"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:141
|
||||
#: includes/admin/class-wp360view-admin.php:161
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:161
|
||||
msgid "Add 360 Product images"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:161
|
||||
msgid "Add to 360 Product gallery"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:161
|
||||
msgid "Delete 360 Product image"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-admin.php:161
|
||||
msgid "Add 360 product images"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:39
|
||||
msgid "360 View Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:56
|
||||
msgid "Shortcode Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:78
|
||||
msgid "Advance Settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:88
|
||||
msgid "Enable Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:90
|
||||
msgid "Enable navigation panel"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:91
|
||||
msgid "Enable or disable navigation panel globally OR you can override this settings by <b>\"navigation\"</b> attibute by shortcode. Default value is <b>true</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:99
|
||||
#: includes/admin/class-wp360view-settings.php:101
|
||||
msgid "Enable dragging"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:102
|
||||
msgid "Enable or disable dragging option globally OR you can override this settings by <b>\"drag\"</b> attibute by shortcode. Default value is <b>true</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:106
|
||||
#: includes/admin/class-wp360view-settings.php:110
|
||||
msgid "Play Speed"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:111
|
||||
msgid "Add/change play speed of 360 slider globally OR you can override this settings by <b>\"playspeed\"</b> attibute by shortcode. Default value is <b>100</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:115
|
||||
#: includes/admin/class-wp360view-settings.php:119
|
||||
msgid "Frame Rate"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:120
|
||||
msgid "Add/change frame rate of 360 slider globally OR you can override this settings by <b>\"framerate\"</b> attibute by shortcode. Default value is <b>10</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:128
|
||||
msgid "Enable Spin"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:130
|
||||
msgid "Enable spin"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:131
|
||||
msgid "Enable or disable spin settings globally OR you can override this settings by <b>\"enablespin\"</b> attibute by shortcode. Default value is <b>false</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:139
|
||||
#: includes/admin/class-wp360view-settings.php:141
|
||||
msgid "Show Cursor"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:142
|
||||
msgid "Hide or show cursor globally OR you can override this settings by <b>\"showcursor\"</b> attibute by shortcode. Default value is <b>false</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:151
|
||||
msgid "Fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:153
|
||||
msgid "Enable full screen support"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:154
|
||||
msgid "Enable or disable full screen support settings globally OR you can override this settings by <b>\"fullscreen\"</b> attibute by shortcode. Default value is <b>true</b>."
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:162
|
||||
msgid "Zoom In/Out"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:164
|
||||
msgid "Enable Zoom In/Out"
|
||||
msgstr ""
|
||||
|
||||
#: includes/admin/class-wp360view-settings.php:165
|
||||
msgid "Enable or disable zoom in/out settings globally OR you can override this settings by <b>\"zoominout\"</b> attibute by shortcode. Default value is <b>true</b>"
|
||||
msgstr ""
|
||||
|
||||
#: templates/360-product.php:22
|
||||
#: templates/shortcode-template.php:26
|
||||
msgid "360 Product View"
|
||||
msgstr ""
|
||||
|
||||
#: wp_360view.php:134
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: wp_360view.php:176
|
||||
msgid "WooCommerce"
|
||||
msgstr ""
|
||||
156
spec/fixtures/dynamic_finders/plugin_version/4partners/translation_file/languages/4partners-ru_RU.po
vendored
Normal file
156
spec/fixtures/dynamic_finders/plugin_version/4partners/translation_file/languages/4partners-ru_RU.po
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# Copyright (C) 2022 4partners
|
||||
# This file is distributed under the GPL2.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 4partners 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/4partners\n"
|
||||
"POT-Creation-Date: 2022-10-13T14:15:50+00:00\n"
|
||||
"PO-Revision-Date: 2022-10-13 17:18+0300\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"X-Domain: 4partners\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
#. Author of the plugin
|
||||
msgid "4partners"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
#. Description of the plugin
|
||||
msgid "-"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "4partners.io"
|
||||
msgstr ""
|
||||
|
||||
#: classes/Plugin.php:145
|
||||
msgid ""
|
||||
"4partners plugin error: please install and activate WooCommerce wordpress "
|
||||
"plugin"
|
||||
msgstr ""
|
||||
"Ошибка плагина 4partners: пожалуйста, установите и активируйте WooCommerce "
|
||||
"плагин"
|
||||
|
||||
#: classes/Plugin.php:152
|
||||
msgid ""
|
||||
"4partners plugin error: please install and activate Cyr-To-Lat wordpress "
|
||||
"plugin"
|
||||
msgstr ""
|
||||
"Ошибка плагина 4partners: пожалуйста, установите и активируйте Cyr-To-Lat "
|
||||
"wordpress плагин"
|
||||
|
||||
#: classes/Services/CategoryService.php:164
|
||||
msgid "4partners price adjustment"
|
||||
msgstr "4partners увеличение цены"
|
||||
|
||||
#: classes/Services/CategoryService.php:176
|
||||
msgid "No less than"
|
||||
msgstr "Не менее чем"
|
||||
|
||||
#: classes/Services/ProductService.php:52
|
||||
msgid "Fix product field values"
|
||||
msgstr "Фиксировать значение полей товара"
|
||||
|
||||
#: classes/Services/ProductService.php:59
|
||||
msgid "Title"
|
||||
msgstr "Название"
|
||||
|
||||
#: classes/Services/ProductService.php:62
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
#: classes/Services/ProductService.php:65
|
||||
#: classes/Services/SettingsService.php:298
|
||||
msgid "Category"
|
||||
msgstr "Категория"
|
||||
|
||||
#: classes/Services/SettingsService.php:58
|
||||
#: classes/Services/SettingsService.php:133
|
||||
msgid "Synchronization"
|
||||
msgstr "Синхронизация"
|
||||
|
||||
#: classes/Services/SettingsService.php:59
|
||||
#: classes/Services/SettingsService.php:141
|
||||
#: classes/Services/SettingsService.php:385
|
||||
msgid "Categories"
|
||||
msgstr "Категории"
|
||||
|
||||
#: classes/Services/SettingsService.php:222
|
||||
msgid "Product catalog language"
|
||||
msgstr "Язык каталога товаров"
|
||||
|
||||
#: classes/Services/SettingsService.php:230
|
||||
msgid "Daily"
|
||||
msgstr "Ежедневно"
|
||||
|
||||
#: classes/Services/SettingsService.php:231
|
||||
msgid "Twice daily"
|
||||
msgstr "Дважды в день"
|
||||
|
||||
#: classes/Services/SettingsService.php:232
|
||||
msgid "Weekly"
|
||||
msgstr "Еженедельно"
|
||||
|
||||
#: classes/Services/SettingsService.php:240
|
||||
msgid "How often to sync products?"
|
||||
msgstr "Как часто синхронизировать товары?"
|
||||
|
||||
#: classes/Services/SettingsService.php:288
|
||||
msgid "Please check categories for import from API"
|
||||
msgstr "Пожалуйста, выберите категории для синхронизации с API"
|
||||
|
||||
#: classes/Services/SettingsService.php:295
|
||||
msgid "Check all"
|
||||
msgstr "Выбрать все"
|
||||
|
||||
#: classes/Services/SettingsService.php:299
|
||||
msgid "Amount"
|
||||
msgstr "Кол-во"
|
||||
|
||||
#: classes/Services/SettingsService.php:300
|
||||
msgid "Started at"
|
||||
msgstr "Начало"
|
||||
|
||||
#: classes/Services/SettingsService.php:301
|
||||
msgid "Ended at"
|
||||
msgstr "Окончание"
|
||||
|
||||
#: classes/Services/SettingsService.php:302
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: classes/Services/SettingsService.php:303
|
||||
msgid "Items loaded"
|
||||
msgstr "Товаров загружено"
|
||||
|
||||
#: classes/Services/SettingsService.php:357
|
||||
msgid "Processing..."
|
||||
msgstr "В процессе..."
|
||||
|
||||
#: classes/Services/SettingsService.php:360
|
||||
msgid "Error"
|
||||
msgstr "Ошибка"
|
||||
|
||||
#: classes/Services/SettingsService.php:362
|
||||
msgid "Completed"
|
||||
msgstr "Завершен"
|
||||
|
||||
#: classes/Services/SettingsService.php:386
|
||||
msgid "Products"
|
||||
msgstr "Товары"
|
||||
|
||||
#: classes/Services/SettingsService.php:388
|
||||
msgid "Progress"
|
||||
msgstr "Прогресс"
|
||||
|
||||
#: classes/Services/SettingsService.php:440
|
||||
msgid "Checked categories"
|
||||
msgstr "Выбранные категории"
|
||||
@@ -0,0 +1,2 @@
|
||||
/**1.0.0 - 2022.04.01**/
|
||||
~ The first released.
|
||||
344
spec/fixtures/dynamic_finders/plugin_version/Ultimate_VC_Addons/change_log/changelog.txt
vendored
Normal file
344
spec/fixtures/dynamic_finders/plugin_version/Ultimate_VC_Addons/change_log/changelog.txt
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
3.19.11 - 22 July 2021
|
||||
- Improvement: Compatibility with the WordPress 5.8
|
||||
- Fix: Advanced Carousel element not working properly.
|
||||
- Fix: The Price Box element is not showing horizontally.
|
||||
- Fix: Hotspot module styling options are not applying properly.
|
||||
- Fix: Functional code is showing when the interactive banner is used with the Advanced carousel.
|
||||
|
||||
3.19.10 - 04 June 2021
|
||||
- Improvement: Compatibility with the latest JavaScript and CSS standard rule.
|
||||
- Improvement: Added the prefix to all the PHP function and class name to avoid future conflicts.
|
||||
- Improvement: Added the prefix to the global variable, script and style handlers.
|
||||
- Fix: Fixed the PHP error foreach() argument must be of type array|object.
|
||||
- Fix: Fixed the PHP notice undefined index into the google font manager.
|
||||
|
||||
3.19.9 - 18 Feb 2021
|
||||
- Improvement : Updated the Smooth-scroll library.
|
||||
- Fix : Ultimate Icon conflict issue with Yoast SEO.
|
||||
- Fix : Console error unable to preventDefault inside passive event listener due to the target being treated as passive.
|
||||
- Fix : Console error cannot read property 'msie' of undefined.
|
||||
- Fix : Youtube video background is not working on MacOSX BigSur.
|
||||
- Fix : Console error cannot read property '1' of null.
|
||||
|
||||
3.19.8 - 12 Dec 2020
|
||||
- Improvement: Shortcode compatibility with PHP 8.0 – Deprecated: Function ultimate_wrap_shortcode_in_div().
|
||||
- Fix: Deprecated jquery issue into Interactive Mouse Parallax row background after WordPress - 5.6
|
||||
- Fix: Console warning jQuery.browser is deprecated after WordPress - 5.6
|
||||
- Fix: Console warning indexOf is not a function after WordPress - 5.6
|
||||
- Fix: Console warning jquery-fn-load is deprecated for below elements after WordPress - 5.6
|
||||
- Heading
|
||||
- Countdown
|
||||
- Creative-link
|
||||
- Dual-Button
|
||||
- Filp-Box
|
||||
- iHover
|
||||
- Info-banner
|
||||
- Info-Box
|
||||
- Info-circle
|
||||
- Modal popup
|
||||
- Team Module
|
||||
- Content Box
|
||||
- Image separator
|
||||
- Google Map
|
||||
- Advanced carousel
|
||||
|
||||
- Fix: Console warning pseudo-event is deprecated for below modules after WordPress - 5.6
|
||||
- Advanced Button
|
||||
- Flip-Box
|
||||
- Interactive Banner
|
||||
|
||||
3.19.7 - 09 Nov 2020
|
||||
- Improvement: Updated the jparallax.js library for the parallax effect.
|
||||
- Improvement: Updated the strings into the backend.
|
||||
- Fix - Console warning jquery-fn-load-is-deprecated.
|
||||
- Fix - Interactive Mouse Parallax row background not working.
|
||||
- Fix - Typography is not applied to prefix into the Fancy text element.
|
||||
|
||||
3.19.6 - 12 Aug 2020
|
||||
- Improvement: Compatibility to WordPress 5.5.
|
||||
- Fix: Google Fonts are not loading into the Google Font Manager tab for WordPress 5.5.
|
||||
- Fix: Upload the custom icon support is not working for WordPress 5.5.
|
||||
- Fix: Save button functionality is not working for the elements with the WordPress 5.5.
|
||||
- Fix: Switch buttons of the Element Tab and Debug Tab are not working with the WordPress 5.5.
|
||||
|
||||
3.19.5 - 16 June 2020
|
||||
- New: Users can now share non-personal usage data to help us test and develop better products. ( <a href="https://store.brainstormforce.com/usage-tracking/?utm_source=changelog&utm_medium=changelog&utm_campaign=usage_tracking" target="_blank" rel="noopener">Know More</a> )
|
||||
- Fix: Fixed the flip-box background overlapping issue into firefox.
|
||||
- Fix: Fixed the duplicate ID issue into the Counter element.
|
||||
- Fix: Fixed the PHP notice issue with the PHP 7.4
|
||||
- Fix: Breaking the UI for the video element while using the Vimeo link.
|
||||
- Fix: Fixed the PHP notice trying to access array offset on the value of type bool.
|
||||
|
||||
3.19.4 - 12 March 2020
|
||||
- Improvement: Updated Dual Color Heading element code for WPML compatibility.
|
||||
- Fix: PHP Notice of $icon_img variable is not defined.
|
||||
- Fix: Interactive Banner Captions come over the sticky header while scrolling.
|
||||
- Fix: PHP Notice of $img_width variable is not defined.
|
||||
- Fix: The hover text color of button2 stopped working for Dual button.
|
||||
- Fix: PHP Notice of $icon_size variable is not defined.
|
||||
- Fix: Rendering issue when background is not set for flip-box.
|
||||
- Fix: PHP Notice of $icon_border_radius variable is not defined.
|
||||
- Fix: Update the strings inside the modules.
|
||||
- Fix: PHP Notice of $icon_border_spacing variable is not defined.
|
||||
|
||||
3.19.3 - 20 Feb 2020
|
||||
- Improvement: Compatibility with latest WordPress PHP_CodeSniffer rules.
|
||||
|
||||
3.19.2 - 03 Feb 2020
|
||||
- Improvement: Hardened the security of the plugin.
|
||||
|
||||
3.19.1 - 22 Jan 2020
|
||||
- Security Fix: Cross-site scripting (XSS) vulnerability.
|
||||
|
||||
3.19.0 - 30 July 2019
|
||||
- New: Introducing Dual Color Heading Element.
|
||||
- Improvement: Added the Extra class option for the Hotspot item.
|
||||
- Improvement: Update WPML XML file for Compatibility.
|
||||
- Improvement: Update the string as an Element instead of Modules in backend settings.
|
||||
- Fix: PHP Notice of $ub variable is not initialized.
|
||||
- Fix: Hotspot glow animation color is not working.
|
||||
- Fix: PHP Warning in Team element appearing on the front end.
|
||||
- Removed purchase key License activation method as the API for this is now being deprecated by Envato.
|
||||
|
||||
3.18.0 - 18 Feb 2019
|
||||
- New: Introduce Ribbon element.
|
||||
- Improvement: Added the animation option for a marker in Google Map.
|
||||
- Fix: Advanced Carousel rendering issue when page refresh.
|
||||
- Fix: PHP Notice Undefined license-form-method variable.
|
||||
|
||||
3.17.1 - 6 Dec 2018
|
||||
- Improvement: Added Text transform option for Fancy text.
|
||||
- Improvement: Update WPML xml file for Compatibility.
|
||||
- Improvement: Added license key purchase form button in debug screen.
|
||||
- Fix: Spacing issue in Fancy text.
|
||||
- Fix: Advanced Carousel doesn't slide properly with one at a time option on Tablet and Mobile devices.
|
||||
|
||||
3.17.0 - 29 Oct 2018
|
||||
- New: Introduce Video element.
|
||||
- Improvement: Toolip will display in case of link in Just Icon.
|
||||
- Fix: Fancy Text not consistent in slide up option.
|
||||
- Removed purchase key License activation method as the API for this is now being deprecated by Envato.
|
||||
|
||||
3.16.26 - 27-Sept-2018
|
||||
- Improvement: Added Border radius option for Flip Box.
|
||||
- Fix: Advanced Tab collapsed when the value is not set for the Active tab.
|
||||
- Fix: Control option not working when Load script globally option is enabled in the hosted video.
|
||||
- Fix: Youtube video not working when the Viewport option is enabled.
|
||||
|
||||
3.16.25 - 22-Aug-2018
|
||||
- Improvement: Added Modal on menu option in Debug setting.
|
||||
- Improvement: Added Description color option for Flip Box.
|
||||
- Improvement: Updated YTplayer JS library for YouTube video.
|
||||
- Improvement: Updated fancy text element code for WPML compatibility.
|
||||
- Fix: Content visibility issue on mobile device in Advanced tab on accordion mode.
|
||||
- Fix: CSS duplication issue on resize in dual button element.
|
||||
- Fix: Timeline position issue in RTL condition.
|
||||
- Fix: Advanced carousel show slide issue in tab and mobile.
|
||||
|
||||
3.16.24 - 28-may-2018
|
||||
- Improvement: Updated registration form popup for updater with GDPR Compliance.
|
||||
- Improvement: Changed license to GPL v2.
|
||||
|
||||
3.16.23 - 15-may-2018
|
||||
- Improvement: Added post/page title select option for headings.
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for Timeline.
|
||||
- Improvement: Added custom JS option on click of the advanced button.
|
||||
- Fix: Advanced Tabs accordion issue on default active tab.
|
||||
- Fix: Set false to PauseOnFocus in advance carousel settings.
|
||||
- Fix: Flipbox visibility issue while using custom height option.
|
||||
|
||||
3.16.22 - 11-April-2018
|
||||
- Improvement: Updated page builder name as WPBakery Page Builder instead of visual composer.
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for package title and for subheading in Info table.
|
||||
- Improvement: New registration form popup for updater.
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for list item title in Info list.
|
||||
- Improvement: Added Focus on select option on advanced carousel.
|
||||
- Improvement: Improve UI.
|
||||
- Fix: Rel Attribute option space issue.
|
||||
- Fix: Icon not uploaded due to server issue.
|
||||
- Fix: Advanced tab js causing issue in IE.
|
||||
- Fix: Flipbox module animation issue in firefox browser.
|
||||
- Fix: Info circle item animation issue in different Browsers while initial load.
|
||||
|
||||
3.16.21 - 3-January-2018
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for package title and for subheading in Price Box.
|
||||
- Fix: Conflict with venus theme function name.
|
||||
- Fix: Counter in Module's list have different name on page element list.
|
||||
- Fix: Dual button height issue on First loading with Advanced Tab.
|
||||
- Fix: Advanced Tabs ID does not work in URL.
|
||||
- Fix: HTML validation error in counter element.
|
||||
- Fix: RTL issue in effect 18 of ihover element.
|
||||
- Fix: Rel Attribute option is not working in advance button.
|
||||
- Fix: Space issue in anchor tag attribute.
|
||||
- Fix: Change the labels from optimized to combined in script & style tab and separator instead of seperator in heading element.
|
||||
|
||||
3.16.20 - 21-November-2017
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for title in Info-banner.
|
||||
- Improvement: Update WPML xml file for Compatibility.
|
||||
- Fix: Advanced Tab Active Tab option issue.
|
||||
- Fix: WPBakery Page Builder map element has issue with advanced tabs.
|
||||
- Fix: Fancy text issue with special character(&) in string.
|
||||
- Fix: Info circle connector alignment issue in RTL condition.
|
||||
- Fix: Info circle item animation issue in Safari Browser.
|
||||
- Fix: Modal Box - Close Modal On Overlay Click and ESC not working when selector option is used.
|
||||
- Fix: Info-circle border not applied properly in safari browser.
|
||||
- Fix: Interactive banner2 link redirect issue in touch devices.
|
||||
- Fix: Toggle button issue while using Visual Composer starter theme.
|
||||
|
||||
3.16.19.1 - 13-November-2017
|
||||
- Fix: Row background pattern images are not showing in effect tab.
|
||||
|
||||
3.16.19 - 6-November-2017
|
||||
- Improvement: Added info list border type option.
|
||||
- Improvement: Optimize plugin code and improved performance.
|
||||
- Improvement: Added padding option for info-circle item.
|
||||
- Improvement: Added time delay option for redirecting the links on touch devices in interactive banner2.
|
||||
- Fix: Info circle clipped at bottom / top is not working properly.
|
||||
- Fix: Info circle image alignment issue.
|
||||
- Fix: Advanced Tab content height issue on First loading with animation style.
|
||||
- Fix: Anchor tag link and tooltip issue in Just Icon.
|
||||
- Fix: Anchor tag link issue in Icon.
|
||||
- Fix: Timeline issue without timeline item disappear.
|
||||
- Fix: Js error in row background.
|
||||
- Fix: Smooth Scroll issue in Chrome Browser.
|
||||
- Fix: Dual button getting collapse in Advanced Tabs.
|
||||
|
||||
3.16.18 - 20-September-2017
|
||||
Security Fix: A cross-site scripting (XSS) vulnerability was discovered in html links, WordPress core has patched it's vulnerability in 4.8.2 release and we've also fix it for Ultimate Addons for Visual Composer.
|
||||
|
||||
3.16.17 - 13-September-2017
|
||||
- Improvement: Added modal Close icon design feature.
|
||||
- Improvement: Added modal popup close on ESC key.
|
||||
- Improvement: Added hover color option for button in Modal.
|
||||
- Improvement: Added modal hide feature on page load for mobile/tablet devices.
|
||||
- Improvement: Advance Tab navigation icon for accordion updated.
|
||||
- Fix: Need to change CSS for pan style in Info banner element.
|
||||
- Fix: Info circle responsive issue.
|
||||
|
||||
3.16.16 - 29-August-2017
|
||||
- Improvement: Advanced Tab ID is now editable.
|
||||
- Improvement: Link markup condition for team element need improvement.
|
||||
- Improvement: Added image alignment option for image in image separator.
|
||||
- Fix: Row separator tilt left right issue.
|
||||
- Fix: Info-Circle does not include image in description area.
|
||||
- Fix: Info-Circle animation not working properly.
|
||||
- Fix: Hosted video background height issue.
|
||||
- Fix: Video background placeholder images do not show up after video completes.
|
||||
- Fix: Timeline right side item spacing issue.
|
||||
- Fix: Timeline has html markup issue and point issue.
|
||||
- Fix: Scripts Loading issue in Carousel.
|
||||
- Fix: Scripts Loading issue in Fancy text.
|
||||
|
||||
3.16.15 - 16-August-2017
|
||||
- Improvement: Added tag options for titles in Flipbox.
|
||||
- Improvement: iHover style addition.
|
||||
- Fix: Info List icon position in RTL should not change.
|
||||
- Fix: Fancy text slide up effect is not working in the Advanced tab.
|
||||
- Fix: Advanced carousel dot navigation color option is not working.
|
||||
- Fix: Dual button getting collapse in expandable section.
|
||||
- Fix: Carousel loading issue in tabs.
|
||||
- Fix: Interactive banner-2 title alignment issue.
|
||||
- Fix: iHover style not working in Internet Explorer.
|
||||
|
||||
3.16.14.1 - 11-August-2017
|
||||
- Fix: Element converting into text-blocks.
|
||||
|
||||
3.16.14 - 1-August-2017
|
||||
- Improvement: Added div, paragraph and span tag options with heading tags for title in modules.
|
||||
- Improvement: Interactive banner added Title tags option.
|
||||
- Improvement: iHover - added Title tags option.
|
||||
- Improvement: Compress plugin images.
|
||||
- Fix: Timeline issue with the link.
|
||||
- Fix: Info box alignment issue with icon at right with heading.
|
||||
- Fix: Dual button font size and line height option not working.
|
||||
- Fix: Hotspot RTL Compatibility.
|
||||
- Fix: Just icon tooltip text is not working.
|
||||
- Fix: Fatal error for redeclaration class in modules.
|
||||
- Fix: Advanced tabs scroll issue while click on tab.
|
||||
|
||||
3.16.13 - 18-July-2017
|
||||
- Improvement: Optimize all the plugin code.
|
||||
- Improvement: Provide filters for theme authors to disable enqueing google fonts in front end.
|
||||
- Fix: Flipbox flip not working on some of the websites.
|
||||
|
||||
3.16.12 - 4-May-2017
|
||||
- Fix: PHP Warning in font manager appearing on front end for some users.
|
||||
|
||||
3.16.11 - 29-Apr-2017
|
||||
- Improved overall security of the plugin by added sanitization wherever required, All the Ajax actions are now checked for user capabilities and nounce to harden the security.
|
||||
- Fix: Dual button not working properly for the second style.
|
||||
- Fix: WooCommere compatibility for version v3.0.4.
|
||||
|
||||
3.16.10 - 07-Apr-2017
|
||||
- Fix: Google Fonts Manager loading fonts with http instead of https in the preview.
|
||||
- Fix: Google Fonts URL returning 404 if the generated URL had duplicate '|' character.
|
||||
- Fix: JavaScript error on WooCommerce v3.0 product pages.
|
||||
- Fix: Option disable parallax on mobile not working.
|
||||
- Fix: Info list aligning besides each other instead of one below other.
|
||||
|
||||
3.16.9 - 07-Mar-2017
|
||||
- Fix: Token invalid error appearing for some users when activating the license. We apologize for the inconvenience.
|
||||
- Fix: Dual button icon images not aligned to center.
|
||||
- Fix: Dual button second button linking to the first buttons link.
|
||||
- Fix: Dual button first button background size option not working when "Design your own" option is selected.
|
||||
- Fix: Advanced Tabs causing Javascript errors on pages with anchors with # links.
|
||||
- Fix: Advanced button "rel" option not working.
|
||||
- Fix: Some users having issues with appear animations not triggering correctly when the row/element is in the viewport.
|
||||
|
||||
3.16.8 - 20-Feb-2017
|
||||
- New: Added WPML Compatibility.
|
||||
- New: Option to pause on hover and center mode in Advanced carousel
|
||||
- New: Option to open selected tab by providing tab index number.
|
||||
- New: Option for title alignment in expandable section element.
|
||||
- New: Added margin/padding options for highlight box.
|
||||
- New: Option to select Zoom control position in Google maps element.
|
||||
- New: Added Typography option for Countdown.
|
||||
- New: All new license activation method to activate license key with just one click.
|
||||
- Improvement: Added aria labels for Next/Prev buttons in Advanced Carousel.
|
||||
- Improvement: RTL Support for All the elements.
|
||||
- Improvement: Rel and Title tag for all the links in all elements.
|
||||
- Improvement: Maps - Added option to enable/disable dragging effect on the desktop.
|
||||
- Improvement: Info Box - Added option to select heading tags for the title.
|
||||
- Improvement: Modal Box - Added support for hosted videos in the modal box, Add any video with WordPress media selector and Select "Hosted video" in option What is this video about.
|
||||
- Improvement: Optimized images in the plugins package.
|
||||
- Fixed: Ultimate Addons menu not being registered in some multisite environments.
|
||||
- Fixed: JavaScript files not being loaded on pages even if shortcode was present on a page.
|
||||
- Fixed: Animation effects in advanced carousel not working.
|
||||
- Fixed: Interactive banner 2 - Multiple interactive banners opening links in new tab, each link did not open a new tab, rather loaded the page in the same new tab.
|
||||
- Fixed: Info list - List alignment set to right breaks the content alignment to enter.
|
||||
- Fixed: Disable Parallax on mobile option not working.
|
||||
- Fixed: Insufficient memory error when activating the plugin from WP-CLI.
|
||||
- Fixed: Flipbox center aligned not working on mobile devices.
|
||||
|
||||
3.16.7 - 04-Aug-2016
|
||||
- Fixed: Appear animation conflict causing pages to creash in salient theme.
|
||||
- Fixed: Flip boxes not working when added inside advanced carousel on mobile phones.
|
||||
- Fixed: Info list causing descriptions not aligned in the center of adjacent icons.
|
||||
- Fixed: Appear animation breaking for some users.
|
||||
- Updaed slick js to latest version which fixes compatibility issues in Ultimate Carousel.
|
||||
- Lots of minor bug fixes and browser compatibility fixes.
|
||||
|
||||
3.16.6
|
||||
- Fixed: Font Icons - SSL issue for $_SERVER[HTTPS] failing
|
||||
- Fixed: Icon Manager - Font zip are not showing after being uploaded
|
||||
- Fixed: Icon Manager - Filetype x-zip allowed to upload
|
||||
- Fixed: Advacned Button - Animation issue while background image applied
|
||||
- Fixed: Video backgrounds - Safari browser alignment issue
|
||||
- Improvement: Google Maps - Changed Google Map policy support to new domains with API key required - http://bsf.io/google-map-api-key
|
||||
|
||||
3.16.5
|
||||
- Fixed: PHP 5.2 fatal error for transient fallback
|
||||
|
||||
3.16.4
|
||||
- Fixed: Video Backgrounds - VC stretch row and full height conflict
|
||||
- Fixed: Hosted Video background - JS console error
|
||||
- Fixed: IB 2 - Style 11 iOS issue
|
||||
- Fixed: Image param - content pass as array instead string
|
||||
- Fixed: Hotspot - Misalignment
|
||||
- Fixed: Row Backgrounds - Image separator conflict with full height option
|
||||
- Fixed: Admin - Redux CSS conflicts with UAVC
|
||||
- Fixed: Timeline - Backend structure break due image alignment
|
||||
- Fixed: Multiple video backgrounds - Poster images not showing on mobile devices
|
||||
- Improvement - Advanced Tabs - Responsive accordion scroll to container on open tab option - http://bsf.io/lmde8
|
||||
- Improvement - Advanced Button - Inline alignment option added to display buttons inline - http://bsf.io/bvkn4
|
||||
- BSF Core v1.17 - With fallback to W3 Total Cache's deleting transients on every page reload
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "a-note-above",
|
||||
"version": "1.0.1",
|
||||
"description": "A way to keep notes on your dashboard.",
|
||||
"author": "Josh Brown <joshbrown101@gmail.com>",
|
||||
"license": "GPLv2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack --watch --progress --hide-modules",
|
||||
"dev-build": "webpack -d --mode development",
|
||||
"build": "webpack -p --mode production"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"vue": "^2.6.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.13",
|
||||
"@babel/preset-env": "latest",
|
||||
"babel-loader": "^8.2.2",
|
||||
"browser-sync": "^2.26.14",
|
||||
"browser-sync-webpack-plugin": "^2.3.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"file-loader": "^4.3.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"html-webpack-template": "^6.2.0",
|
||||
"less": "^3.13.1",
|
||||
"less-loader": "^5.0.0",
|
||||
"mini-css-extract-plugin": "^0.8.2",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"url-loader": "^2.3.0",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Abandoned Cart for WooCommerce 1.0.0\n"
|
||||
"POT-Creation-Date: 2021-03-25 19:20+0530\n"
|
||||
"PO-Revision-Date: 2021-03-25 19:20+0530\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: MakeWebBetter\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_n;_x;_ex;_nx;esc_attr__;esc_attr_e;esc_attr_x;"
|
||||
"esc_html__;esc_html_e;esc_html_x;_n_noop;_nx_noop;translate_nooped_plural\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: abandoned-cart-for-woocommerce.php:162
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: abandoned-cart-for-woocommerce.php:204
|
||||
msgid ""
|
||||
"Oops! You tried activating the ABANDONED CART FOR WOOCOMMERCE. Please "
|
||||
"activate WooCommerce and then try again."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:232
|
||||
msgid "Email Work Flow"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:236
|
||||
msgid "Abandon Cart Reports "
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:240
|
||||
msgid "Abandon Cart Analytics "
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:244
|
||||
msgid " Overview"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:264
|
||||
msgid "Enable plugin"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:266
|
||||
msgid "Enable plugin to start the functionality."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:271
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:283
|
||||
msgid "YES"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:272
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:284
|
||||
msgid "NO"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:276
|
||||
msgid "Add to Cart Pop-Up"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:278
|
||||
msgid "Enable this to show pop-up at the add to cart time."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:288
|
||||
msgid "Add to Cart Pop-Up Title"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:290
|
||||
msgid "Enter title here to show on add to cart pop-up."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:294
|
||||
msgid "Add to Cart title"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:297
|
||||
msgid "Add to Cart Pop-Up Text"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:299
|
||||
msgid "Enter text here to show on add to cart pop-up."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:303
|
||||
msgid "Add to Cart text"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:306
|
||||
msgid "Cut-off time"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:308
|
||||
msgid "Enter time in HOURS after which a cart will be treated as abandoned."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:313
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:323
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:352
|
||||
msgid "Enter Time"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:316
|
||||
msgid "Delete abandoned cart history"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:318
|
||||
msgid ""
|
||||
"Enter the number of days before which you dont want to keep history of "
|
||||
"abandoned cart. Remain blank to never delete history automatically."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:326
|
||||
msgid "User role for tracking "
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:328
|
||||
msgid ""
|
||||
"Select user roles for which you want to track abandoned carts(By default "
|
||||
"only “GUEST USERS” are tracked)."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:336
|
||||
msgid "Coupon code prefix"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:338
|
||||
msgid ""
|
||||
"Add a pattern in which you want the coupons to be generated for Cart "
|
||||
"Abandoners. Generated coupon will be prefix_<random_5_digit_alphanumeric>."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:342
|
||||
msgid "Enter Coupon code"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:345
|
||||
msgid "Coupon expiry"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:347
|
||||
msgid ""
|
||||
"Enter the number of hours after which coupon will be expired if not used. "
|
||||
"Time will start at the time of coupon send."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:355
|
||||
msgid "Coupon Discount"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:357
|
||||
msgid ""
|
||||
"Enter the percentage discount (between 1-100) which will apply on abandoned "
|
||||
"cart."
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:363
|
||||
msgid "Enter Discount"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:368
|
||||
msgid "Save Settings"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:411
|
||||
msgid "Id of some field is missing"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:414
|
||||
msgid "Settings saved !"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:418
|
||||
msgid " Nonce Not Verified "
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:485
|
||||
msgid "Nonce not verified"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:508
|
||||
msgid "Product Id"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:511
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-product-report.php:71
|
||||
msgid "Product Name"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:514
|
||||
msgid "Quantity"
|
||||
msgstr ""
|
||||
|
||||
#: admin/class-abandoned-cart-for-woocommerce-admin.php:517
|
||||
msgid "Total "
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-admin-dashboard.php:26
|
||||
msgid "Documentation"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-admin-dashboard.php:28
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:125
|
||||
msgid "Support"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:36
|
||||
msgid "Abandoned Carts this Month"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:49
|
||||
msgid "Abandoned Carts till Now"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:64
|
||||
msgid "Recovered Carts this Month"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:80
|
||||
msgid "Recovered Carts till Now"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:95
|
||||
msgid "Recovered Money"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:119
|
||||
msgid "Money That Can Be recovered"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-analytics.php:142
|
||||
msgid "Graph of Abandoned Carts"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:26
|
||||
msgid "Use Placeholders"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:26
|
||||
msgid "to apply a coupon on the cart"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:26
|
||||
msgid "for displaying the cart in the email"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:27
|
||||
msgid " for checkout page"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:52
|
||||
msgid "Enable The workflow"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:71
|
||||
msgid "Initiate Time"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:81
|
||||
msgid "Enter time"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:84
|
||||
msgid "Enter time In Hours"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:90
|
||||
msgid "Mail Subject"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:100
|
||||
msgid "Enter Mail Subject"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:103
|
||||
msgid "Enter Subject"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:109
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-email-workflow.php:125
|
||||
msgid "Save Workflow"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:22
|
||||
msgid "What Is Abandoned Cart For WooCommerce?"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:27
|
||||
msgid ""
|
||||
"Abandoned Cart For WooCommerce is an all-in-one solution to beat an online "
|
||||
"seller’s biggest nightmare, i.e, abandoned carts. With the help of this "
|
||||
"plugin, \n"
|
||||
"\t\t\t\t\tyou can very easily and efficiently win back your lost WooCommerce "
|
||||
"customers and skyrocket your conversion rate."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:33
|
||||
msgid "As a store owner, you get to:"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:35
|
||||
msgid "Analyze deep insights into your abandoned carts and products."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:36
|
||||
msgid "Capture customer emails on the checkout and cart page."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:37
|
||||
msgid "Send automated emails to your lost customers"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:38
|
||||
msgid "Win-back even the unregistered customers"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:39
|
||||
msgid "See a complete list of abandoned carts"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:40
|
||||
msgid "Customizable abandoned cart workflows"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:41
|
||||
msgid "Disable tracking for selected user roles"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:42
|
||||
msgid ""
|
||||
"Create an abandoned cart recovery strategy for even the variable products"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:45
|
||||
msgid "The Free Plugin Benefits"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:53
|
||||
msgid " Advanced Reports For Abandoned Products"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:57
|
||||
msgid ""
|
||||
"The plugin comes with advanced reports for the abandoned carts made in your "
|
||||
"store. Thus, allowing you to \n"
|
||||
"\t\t\t\t\t\t\t\tmake an informed abandoned cart recovery strategy."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:72
|
||||
msgid "Workflow For Abandoned Carts"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:73
|
||||
msgid ""
|
||||
"Abandoned Cart For WooCommerce comes with a customizable workflow that lets "
|
||||
"you send emails and win back your lost customers."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:83
|
||||
msgid "Support Variable Product"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:88
|
||||
msgid ""
|
||||
"The plugin works very well with and supports variable products on your "
|
||||
"WooCommerce store."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:103
|
||||
msgid "Complete List Of Abandoned Users"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:108
|
||||
msgid ""
|
||||
"The plugin gives you a complete list of shoppers that left carts abandoned "
|
||||
"on your WooCommerce store."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-overview.php:129
|
||||
msgid ""
|
||||
"Phone, Email & Skype support. Our Support is ready to assist you regarding "
|
||||
"any query, issue, or feature request and if that doesn't help our Technical "
|
||||
"team will connect with you personally and have your query\n"
|
||||
"\t\t\t\t\t\t\t\tresolved."
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-product-report.php:49
|
||||
msgid "Reports according products-name"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/abandoned-cart-for-woocommerce-product-report.php:74
|
||||
msgid "Abandoned time"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:138
|
||||
msgid "Abandoned"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:140
|
||||
msgid "Recovered"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:198
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:360
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:199
|
||||
msgid "Left Page FROM "
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:200
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:201
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:321
|
||||
msgid "Nonce Not Verified"
|
||||
msgstr ""
|
||||
|
||||
#: admin/partials/class-abandoned-cart-for-woocommerce-report.php:368
|
||||
msgid "Full Details Of Cart"
|
||||
msgstr ""
|
||||
|
||||
#: common/class-abandoned-cart-for-woocommerce-common.php:92
|
||||
msgid "Every custom time"
|
||||
msgstr ""
|
||||
|
||||
#: common/class-abandoned-cart-for-woocommerce-common.php:97
|
||||
msgid "Delete custom time"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:300
|
||||
msgid "What is your monthly revenue?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:319
|
||||
msgid "What industry defines your business?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:325
|
||||
msgid "Industry Type"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:356
|
||||
msgid "What is the best email address to contact you?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:368
|
||||
msgid "What is your contact number?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:373
|
||||
msgid "Contact Number"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:487
|
||||
msgid ""
|
||||
"Let us know why you are deactivating Abandoned Cart for WooCommerce so we "
|
||||
"can improve the plugin"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:491
|
||||
msgid "Reason"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce-onboarding-steps.php:729
|
||||
msgid "Unexpected Error Occured"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce.php:367
|
||||
msgid "General Setting"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce.php:384
|
||||
msgid "Cart"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce.php:388
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-abandoned-cart-for-woocommerce.php:412
|
||||
#, php-format
|
||||
msgid ""
|
||||
"Unable to locate file at location %s. Some features may not work properly in "
|
||||
"this plugin. Please contact us!"
|
||||
msgstr ""
|
||||
|
||||
#: mwb-acwf-gdpr.php:23
|
||||
msgid "Stored Customer Details for Tracking Abandoned cart"
|
||||
msgstr ""
|
||||
|
||||
#: mwb-acwf-gdpr.php:24
|
||||
msgid ""
|
||||
"We store customer's email address, customer's Ip Address so that we can send "
|
||||
"them email reagarding their abandoned cart to cover them"
|
||||
msgstr ""
|
||||
|
||||
#: mwb-acwf-gdpr.php:36
|
||||
msgid "Abandoned Cart For WooCommerce"
|
||||
msgstr ""
|
||||
|
||||
#: mwb-acwf-gdpr.php:54 mwb-acwf-gdpr.php:121
|
||||
msgid "Recipient Details"
|
||||
msgstr ""
|
||||
|
||||
#: mwb-acwf-gdpr.php:166
|
||||
msgid "Removed data of \"Abandoned Cart\""
|
||||
msgstr ""
|
||||
|
||||
#: onboarding/templates/abandoned-cart-for-woocommerce-deactivation-template.php:33
|
||||
msgid "May we have a little info about why you are deactivating?"
|
||||
msgstr ""
|
||||
|
||||
#: onboarding/templates/abandoned-cart-for-woocommerce-deactivation-template.php:44
|
||||
msgid "Skip and Deactivate Now"
|
||||
msgstr ""
|
||||
|
||||
#: onboarding/templates/abandoned-cart-for-woocommerce-onboarding-template.php:27
|
||||
msgid "Welcome to MakeWebBetter"
|
||||
msgstr ""
|
||||
|
||||
#: onboarding/templates/abandoned-cart-for-woocommerce-onboarding-template.php:28
|
||||
msgid ""
|
||||
"We love making new friends! Subscribe below and we promise to keep you up-to-"
|
||||
"date with our latest new plugins, updates, awesome deals and a few special "
|
||||
"offers."
|
||||
msgstr ""
|
||||
|
||||
#: onboarding/templates/abandoned-cart-for-woocommerce-onboarding-template.php:40
|
||||
msgid "Skip For Now"
|
||||
msgstr ""
|
||||
|
||||
#: public/class-abandoned-cart-for-woocommerce-public.php:84
|
||||
msgid "Enter Your Email Here"
|
||||
msgstr ""
|
||||
|
||||
#: public/class-abandoned-cart-for-woocommerce-public.php:232
|
||||
msgid "Do You Want to Buy"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,338 @@
|
||||
# Copyright (C) 2020 ZealousWeb Technologies
|
||||
# This file is distributed under the same license as the Abandoned Contact Form 7 plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Abandoned Contact Form 7 1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/abandoned-forms-contact-form-7\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: 2020-08-17T07:23:53+02:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.4.0\n"
|
||||
"X-Domain: cf7-abandoned-form\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Abandoned Contact Form 7"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Abandoned Contact Form 7 provides an ability to track the data from Contact Form 7 even if the user does not submit the form."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "ZealousWeb Technologies"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://www.zealousweb.com"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:112
|
||||
msgid "Form Data"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:113
|
||||
#: inc/admin/class.cf7af.admin.action.php:508
|
||||
msgid "User Email"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:114
|
||||
#: inc/admin/class.cf7af.admin.action.php:515
|
||||
msgid "User IP"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:115
|
||||
msgid "is Enable Send Mail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:116
|
||||
msgid "Number of Send Mail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:117
|
||||
#: inc/admin/class.cf7af.admin.filter.php:227
|
||||
msgid "Submitted Date"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:169
|
||||
#: inc/admin/class.cf7af.admin.action.php:541
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:170
|
||||
#: inc/admin/class.cf7af.admin.action.php:542
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:219
|
||||
msgid "Abandoned Form Data"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:288
|
||||
#: inc/admin/class.cf7af.admin.action.php:552
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:290
|
||||
msgid "To enable this button please allow mail notification from detail page"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:291
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:381
|
||||
msgid "Select Forms"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:387
|
||||
msgid "Export CSV"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:424
|
||||
#: inc/admin/class.cf7af.admin.action.php:425
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:34
|
||||
msgid "Mail Notification Settings"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:433
|
||||
#: inc/admin/class.cf7af.admin.action.php:434
|
||||
#: inc/admin/class.cf7af.admin.action.php:549
|
||||
#: inc/admin/class.cf7af.admin.filter.php:224
|
||||
msgid "Send Mail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:451
|
||||
msgid "Please select form to export."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:466
|
||||
msgid "No Abandoned data Found"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:501
|
||||
msgid "CF7 Form Name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:522
|
||||
msgid "Other Form Detail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.action.php:538
|
||||
msgid "Disable Mail Notification"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.filter.php:92
|
||||
msgid "Abandoned Form Settings"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.filter.php:222
|
||||
msgid "Abandoned User's Email"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.filter.php:223
|
||||
msgid "IP Address"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.filter.php:225
|
||||
msgid "Number of Emails Sent"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf7af.admin.filter.php:226
|
||||
msgid "Fail Counter"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:13
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:37
|
||||
msgid "Nonce check failed."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:26
|
||||
msgid "Settings saved."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:28
|
||||
msgid "Settings are not saved."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:36
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:96
|
||||
msgid "Use {email} to insert the email into the mail body"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:37
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:97
|
||||
msgid "Use {contact_form} to insert the form name into the mail body"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:38
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:98
|
||||
msgid "Use {link} to insert the page contact link into the mail body"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:61
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:175
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:80
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:196
|
||||
msgid "Email Body"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:101
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:114
|
||||
msgid "<h3>Subject</h3><p>Please enter the subject for send mail.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.notification.settings.template.php:116
|
||||
msgid "<h3>Email Body </h3><p>It's a body content of mail which reflect on sent mail.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:73
|
||||
msgid "Error on Send Mail."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:84
|
||||
msgid "Send Mail Suceessfully to Abandoned User."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:86
|
||||
msgid "Mail has not send."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:92
|
||||
msgid "Send Mail to Abandoned User Entry"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:120
|
||||
msgid "User Email Address (To)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:139
|
||||
msgid "From Name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:157
|
||||
msgid "From Email Address"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:212
|
||||
msgid "Send"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:226
|
||||
msgid "<h3>User Email Address (To)</h3><p>This is an Abandoned user's email ID which will receive the email.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:228
|
||||
msgid "<h3>From Name</h3><p>This is a default 'Name' which is get from website general settings but if you use SMTP settings then From Name used from SMTP settings page.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:230
|
||||
msgid "<h3>From Email Address</h3><p>This is a default 'Email Address' which is get from website general settings but if you use SMTP settings then From Email used from SMTP settings page.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:232
|
||||
msgid "<h3>Subject</h3><p>This is the subject which is used in email.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.send.mail.template.php:234
|
||||
msgid "<h3>Email Body</h3><p>This is an email body content which are reflect on email body.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.template.php:23
|
||||
msgid "Enable Abandoned"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.template.php:34
|
||||
#: inc/admin/template/cf7af.template.php:41
|
||||
msgid "Select Email Field"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.template.php:67
|
||||
msgid "<h3>Enable/Disable Abandoned</h3><p>You can enable/disable Abandoned form functionality.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf7af.template.php:69
|
||||
msgid "<h3>Select Email Field</h3><p>Select the email field for tracking Abandoned user</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:92
|
||||
msgid "Support"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:94
|
||||
msgid "Document"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:345
|
||||
#: inc/class.cf7af.php:356
|
||||
msgid "Abandoned Users"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:346
|
||||
msgid "Abandoned User Detail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:347
|
||||
msgid "All Abandoned Users"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:348
|
||||
msgid "Edit Abandoned User"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:349
|
||||
msgid "Search Abandoned User"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:350
|
||||
msgid "View Abandoned User"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:351
|
||||
msgid "No Abandoned User found"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:352
|
||||
msgid "No Abandoned User found in Trash"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:400
|
||||
msgid "You are so close!"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:402
|
||||
msgid "Hello"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:403
|
||||
msgid "Contact into:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:404
|
||||
msgid "We noticed you left something behind."
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:405
|
||||
msgid "No need to worry, you can still visit the page from where you left accidentally."
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:406
|
||||
msgid "Use the following link to make submissions."
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:408
|
||||
msgid "Thanks!"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf7af.php:424
|
||||
msgid "<b>Abandoned Contact Form 7 :</b> Contact Form 7 is not active! Please install <a target=\"_blank\" href=\"https://wordpress.org/plugins/contact-form-7/\">Contact Form 7</a>."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,66 @@
|
||||
# Copyright (C) 2021 AbsolutePlugins
|
||||
# This file is distributed under the GPLv3 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Absolute Thumbnail Column 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/absolute-thumbnail-column\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: 2021-07-07T14:49:00+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.5.0\n"
|
||||
"X-Domain: absp-thumbnail-column\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Absolute Thumbnail Column"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://absoluteplugins.com/plugins/absolute-thumbnail-column/"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Absolute Thumbnail column allows you to upload, select and change thumbnail on any post-types right from the post table."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "AbsolutePlugins"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://absoluteplugins.com/"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:112
|
||||
msgid "Thumbnail"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:175
|
||||
#: absolute-thumbnail-column.php:177
|
||||
msgid "Click the image to edit or update"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:179
|
||||
#: absolute-thumbnail-column.php:181
|
||||
msgid "Remove featured image"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:189
|
||||
msgid "No Thumb"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:197
|
||||
#: absolute-thumbnail-column.php:199
|
||||
msgid "Set featured image"
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:360
|
||||
msgid "Could not set that as the thumbnail image. Try a different attachment."
|
||||
msgstr ""
|
||||
|
||||
#: absolute-thumbnail-column.php:362
|
||||
msgid "Could not remove the post thumbnail image. Try a again later."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,622 @@
|
||||
# Copyright (C) 2022 AcademyLMS
|
||||
# This file is distributed under the GPL-3.0+.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Academy Starter Templates 1.0.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/academy-starter-templates\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: 2022-02-20T16:36:06+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.5.0\n"
|
||||
"X-Domain: academy-starter-templates\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Academy Starter Templates"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "http://demo.academylms.net"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Demo importer plugin for academy lms."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "AcademyLMS"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "http://academylms.net"
|
||||
msgstr ""
|
||||
|
||||
#: includes/hooks.php:183
|
||||
msgid "No relevent plugin for this demo."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/customizer-importer.php:38
|
||||
#: includes/library/customizer-importer.php:45
|
||||
msgid "Importing customizer settings"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/customizer-importer.php:43
|
||||
msgid "Customizer settings import finished!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - file path
|
||||
#: includes/library/customizer-importer.php:73
|
||||
msgid "Error: The customizer import file is missing! File path: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/customizer-importer.php:93
|
||||
msgid "Error: The customizer import file is not in a correct format. Please make sure to use the correct customizer import file."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/customizer-importer.php:99
|
||||
msgid "Error: The customizer import file is not suitable for current theme. You can only import customizer settings for the same theme or a child theme."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/downloader.php:59
|
||||
msgid "Missing URL for downloading a file!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s and %3$s - strong HTML tags, %2$s - file URL, %4$s - br HTML tag, %5$s - error code, %6$s - error message.
|
||||
#: includes/library/downloader.php:77
|
||||
msgid "An error occurred while fetching file from: %1$s%2$s%3$s!%4$sReason: %5$s - %6$s."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s - br HTML tag, %2$s - file path
|
||||
#: includes/library/helpers.php:196
|
||||
#: includes/library/helpers.php:239
|
||||
msgid "An error occurred while writing file to your server! Tried to write a file to: %1$s%2$s."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s - br HTML tag, %2$s - file path
|
||||
#: includes/library/helpers.php:273
|
||||
msgid "An error occurred while reading a file from your server! Tried reading file from path: %1$s%2$s."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s and %2$s - strong HTML tags, %3$s - HTML link to a doc page.
|
||||
#: includes/library/helpers.php:296
|
||||
msgid "This WordPress page does not have %1$sdirect%2$s write file access. This plugin needs it in order to save the demo import xml file to the upload directory of your site. You can change this setting with these instructions: %3$s."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:313
|
||||
msgid "An error occurred while retrieving reading/writing permissions to your server (could not retrieve WP filesystem credentials)!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:321
|
||||
msgid "Your WordPress login credentials don't allow to use WP_Filesystem!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:361
|
||||
msgid "Academy Starter Templates - "
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s - opening div and paragraph HTML tags, %2$s - closing div and paragraph HTML tags.
|
||||
#: includes/library/helpers.php:395
|
||||
msgid "%1$sYour user role isn't high enough. You don't have permission to import demo data.%2$s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:428
|
||||
msgid "No file provided."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the error message.
|
||||
#: includes/library/helpers.php:456
|
||||
msgid "Content file was not uploaded. Error: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:460
|
||||
#: includes/library/helpers.php:476
|
||||
#: includes/library/helpers.php:492
|
||||
#: includes/library/helpers.php:503
|
||||
#: includes/library/helpers.php:522
|
||||
#: includes/library/helpers.php:530
|
||||
msgid "Upload files"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the error message.
|
||||
#: includes/library/helpers.php:472
|
||||
msgid "Widget file was not uploaded. Error: %s"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the error message.
|
||||
#: includes/library/helpers.php:488
|
||||
msgid "Customizer file was not uploaded. Error: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:501
|
||||
msgid "Missing Redux option name! Please also enter the Redux option name!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the error message.
|
||||
#: includes/library/helpers.php:518
|
||||
msgid "Redux file was not uploaded. Error: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:528
|
||||
msgid "The import files were successfully uploaded!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the max execution time.
|
||||
#: includes/library/helpers.php:554
|
||||
msgid "Initial max execution time = %s"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s - new line break, %2$s - the site URL, %3$s - the file path for content import, %4$s - the file path for widgets import, %5$s - the file path for widgets import, %6$s - the file path for redux import.
|
||||
#: includes/library/helpers.php:558
|
||||
msgid "Files info:%1$sSite URL = %2$s%1$sData file = %3$s%1$sWidget file = %4$s%1$sCustomizer file = %5$s%1$sRedux files:%1$s%6$s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:561
|
||||
#: includes/library/helpers.php:562
|
||||
#: includes/library/helpers.php:563
|
||||
#: includes/library/helpers.php:564
|
||||
msgid "not defined!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/helpers.php:735
|
||||
#: includes/library/helpers.php:736
|
||||
msgid "Academy Starter"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/importer.php:175
|
||||
msgid "New AJAX call!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:215
|
||||
msgid "No preview image defined for this import."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:216
|
||||
msgid "Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:217
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:218
|
||||
msgid "Yes, import!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:219
|
||||
msgid "Selected demo import:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:220
|
||||
msgid "Installing..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:221
|
||||
#: includes/library/wpcli-commands.php:154
|
||||
msgid "Importing..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:222
|
||||
msgid "Successfully Imported!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:223
|
||||
msgid "Install Plugin"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:224
|
||||
msgid "Installed"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:225
|
||||
msgid "Import Failed"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:226
|
||||
msgid "Whoops, there was a problem importing your content."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:227
|
||||
msgid "Looks like some of the plugins failed to install. Please try again. If this issue persists, please manually install the failing plugins and come back to this step to import the theme demo data."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:228
|
||||
msgid "Invalid file type detected! Please select an XML file for the Content Import."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:229
|
||||
msgid "Invalid file type detected! Please select a JSON or WIE file for the Widgets Import."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:230
|
||||
msgid "Invalid file type detected! Please select a DAT file for the Customizer Import."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:231
|
||||
msgid "Invalid file type detected! Please select a JSON file for the Redux Import."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:248
|
||||
msgid "Manual import files are missing! Please select the import files and try again."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:263
|
||||
#: includes/library/one-click-demo-import.php:308
|
||||
msgid "Manually uploaded files"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:320
|
||||
#: includes/library/one-click-demo-import.php:331
|
||||
msgid "Downloaded files"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the name of the selected import.
|
||||
#: includes/library/one-click-demo-import.php:327
|
||||
msgid "The import files for: %s were successfully downloaded!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:335
|
||||
msgid "No import files specified!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:452
|
||||
#: views/import.php:118
|
||||
msgid "Import Complete!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:453
|
||||
#: views/import.php:121
|
||||
msgid "Congrats, your demo was imported successfully. You can now begin editing your site."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:454
|
||||
msgid "Successful Import"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/one-click-demo-import.php:457
|
||||
msgid "Your import completed, but some things may not have imported properly."
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - link to the log file.
|
||||
#: includes/library/one-click-demo-import.php:461
|
||||
msgid "<p><a href=\"%s\" target=\"_blank\">View error log</a> for more information.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:86
|
||||
msgid "WPForms"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:87
|
||||
msgid "Join 4,000,000+ professionals who build smarter forms and surveys with WPForms."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:93
|
||||
msgid "All in One SEO"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:94
|
||||
msgid "Use All in One SEO Pack to optimize your WordPress site for SEO."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:100
|
||||
msgid "MonsterInsights"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:101
|
||||
msgid "The #1 Google Analytics Plugin for WordPress that’s easy and powerful."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:107
|
||||
msgid "Custom Landing Pages by SeedProd"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:108
|
||||
msgid "Work on your site in private while visitors see a \"Coming Soon\" or \"Maintenance Mode\" page."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:113
|
||||
msgid "Smash Balloon Social Photo Feed"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:114
|
||||
msgid "Display beautifully clean, customizable, and responsive Instagram feeds."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:119
|
||||
msgid "WP Mail SMTP"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:120
|
||||
msgid "Make email delivery easy for WordPress. Connect with SMTP, Gmail, Outlook, Mailgun, and more."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:225
|
||||
msgid "Could not install the plugin. You don't have permission to install plugins."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:231
|
||||
msgid "Could not install the plugin. Plugin slug is missing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:236
|
||||
msgid "Plugin is already installed and activated!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:244
|
||||
msgid "Plugin was already installed! We activated it for you."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:252
|
||||
msgid "Could not install the plugin. Don't have file permission."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:292
|
||||
msgid "Plugin installed and activated succesfully."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/plugin-installer.php:299
|
||||
msgid "Could not install the plugin. WP Plugin installer could not retrieve plugin information."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/view-helpers.php:20
|
||||
msgid "Academy Starter Templates"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/view-helpers.php:22
|
||||
msgid "Questionmark icon"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/view-helpers.php:53
|
||||
msgid "Theme screenshot"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:41
|
||||
#: includes/library/widget-importer.php:52
|
||||
msgid "Importing widgets"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:88
|
||||
msgid "Error: Widget import file could not be found."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:118
|
||||
msgid "Error: Widget import data could not be read. Please try a different file."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:156
|
||||
msgid "Sidebar does not exist in theme (moving widget to Inactive)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:177
|
||||
msgid "Site does not support widget"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:210
|
||||
msgid "Widget already exists"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:275
|
||||
msgid "Imported"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:278
|
||||
msgid "Imported to Inactive"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:284
|
||||
msgid "No Title"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/widget-importer.php:331
|
||||
msgid "No results for widget import!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:35
|
||||
msgid "There are no predefined demo imports for currently active theme!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:38
|
||||
msgid "Here are the predefined demo imports:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:72
|
||||
msgid "At least one of the possible options should be set! Check them with --help"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:123
|
||||
msgid "The \"predefined\" parameter should be a number (an index of the OCDI predefined demo import)!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:129
|
||||
msgid "The supplied predefined index does not exist! Please take a look at the available predefined demo imports:"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:136
|
||||
msgid "Predefined demo import started! All other parameters will be ignored!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the name of the selected demo import.
|
||||
#: includes/library/wpcli-commands.php:141
|
||||
msgid "Selected predefined demo import: %s"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:144
|
||||
msgid "Preparing the demo import files..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:149
|
||||
msgid "Demo import files could not be retrieved!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:152
|
||||
msgid "Demo import files retrieved successfully!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:174
|
||||
msgid "Predefined import finished!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:186
|
||||
msgid "Content import file provided does not exist! Skipping this import!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:195
|
||||
msgid "Importing content (this might take a while)..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:197
|
||||
msgid "Importing content"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:202
|
||||
msgid "Content import finished!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:204
|
||||
msgid "There were some issues while importing the content!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:223
|
||||
msgid "Widgets import file provided does not exist! Skipping this import!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:227
|
||||
msgid "Importing widgets..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:232
|
||||
msgid "Widgets imported successfully!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:234
|
||||
msgid "There were some issues while importing widgets!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:253
|
||||
msgid "Customizer import file provided does not exist! Skipping this import!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:257
|
||||
msgid "Importing customizer settings..."
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:262
|
||||
msgid "Customizer settings imported successfully!"
|
||||
msgstr ""
|
||||
|
||||
#: includes/library/wpcli-commands.php:264
|
||||
msgid "There were some issues while importing customizer settings!"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %s - the name of the executing action.
|
||||
#: includes/library/wpcli-commands.php:284
|
||||
msgid "Executing action: %s ..."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:28
|
||||
msgid "Before We Import Your Demo"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:30
|
||||
msgid "To ensure the best experience, installing the following plugins is strongly recommended, and in some cases required."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:43
|
||||
msgid "All required/recommended plugins are already installed. You can import your demo content."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:56
|
||||
#: views/import.php:89
|
||||
msgid "Star icon"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:71
|
||||
#: views/install-plugins.php:49
|
||||
msgid "Checkmark icon"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:73
|
||||
msgid "Lock icon"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:75
|
||||
#: views/install-plugins.php:50
|
||||
msgid "Loading..."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:85
|
||||
msgid "The plugins with %1$s are recommended by Academy Starter Templates plugin to help you grow your website. They are not required for the %2$s theme to work."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:98
|
||||
#: views/install-plugins.php:57
|
||||
msgid "Back icon"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:98
|
||||
#: views/install-plugins.php:57
|
||||
msgid "Go Back"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:99
|
||||
msgid "Continue & Import"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:108
|
||||
msgid "Importing Content"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:109
|
||||
msgid "Please sit tight while we import your content. Do not refresh the page or hit the back button."
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:112
|
||||
msgid "Importing animation"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:129
|
||||
msgid "Theme Settings"
|
||||
msgstr ""
|
||||
|
||||
#: views/import.php:130
|
||||
msgid "Visit Site"
|
||||
msgstr ""
|
||||
|
||||
#: views/install-plugins.php:25
|
||||
msgid "Install Recommended Plugins"
|
||||
msgstr ""
|
||||
|
||||
#: views/install-plugins.php:27
|
||||
msgid "Want to use the best plugins for the job? Here is the list of awesome plugins that will help you achieve your goals."
|
||||
msgstr ""
|
||||
|
||||
#: views/install-plugins.php:58
|
||||
msgid "Install & Activate"
|
||||
msgstr ""
|
||||
|
||||
#. translators: %1$s - the opening div and paragraph HTML tags, %2$s and %3$s - strong HTML tags, %4$s - the closing div and paragraph HTML tags.
|
||||
#: views/plugin-page.php:27
|
||||
msgid "%1$sWarning: your server is using %2$sPHP safe mode%3$s. This means that you might experience server timeout errors.%4$s"
|
||||
msgstr ""
|
||||
|
||||
#: views/plugin-page.php:50
|
||||
msgid "All Demos"
|
||||
msgstr ""
|
||||
|
||||
#: views/plugin-page.php:63
|
||||
msgid "Search Demos..."
|
||||
msgstr ""
|
||||
|
||||
#: views/plugin-page.php:86
|
||||
msgid "No preview image."
|
||||
msgstr ""
|
||||
|
||||
#: views/plugin-page.php:93
|
||||
msgid "Preview Demo"
|
||||
msgstr ""
|
||||
|
||||
#: views/plugin-page.php:95
|
||||
msgid "Import Demo"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,55 @@
|
||||
# Copyright (C) 2022 Accedeme
|
||||
# This file is distributed under the GPLv2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Accedeme for WP 0.2\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-accedeme\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: 2022-07-03T18:09:27+02:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.6.0\n"
|
||||
"X-Domain: wp-accedeme\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Accedeme for WP"
|
||||
msgstr ""
|
||||
|
||||
#. Plugin URI of the plugin
|
||||
msgid "https://accedeme.com/plataforma-framework/wordpress"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Añade a tu sitio WordPress una capa de accesibilidad. Permite que cualquiera pueda acceder a tu página web independientemente de sus capacidades, conocimientos y del dispositivo usado."
|
||||
msgstr "Añade a tu sitio WordPress una capa de accesibilidad. Permite que cualquiera pueda acceder a tu página web independientemente de sus capacidades, conocimientos y del dispositivo usado."
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Accedeme"
|
||||
msgstr "Accedeme"
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://accedeme.com/"
|
||||
msgstr "https://accedeme.com/"
|
||||
|
||||
#: admin/wp-accedeme-admin.php:27
|
||||
msgid "No tiene suficientes permisos para acceder a esta página."
|
||||
msgstr "No tiene suficientes permisos para acceder a esta página."
|
||||
|
||||
#: admin/wp-accedeme-admin.php:46
|
||||
msgid "WP Accedeme » Settings"
|
||||
msgstr "WP Accedeme » Settings"
|
||||
|
||||
#: admin/wp-accedeme-admin.php:57
|
||||
msgid "Panel de control"
|
||||
msgstr "Panel de control"
|
||||
|
||||
#: admin/wp-accedeme-admin.php:64
|
||||
msgid "Ya sólo queda registrar tu dominio en accedeme.com"
|
||||
msgstr "Ya sólo queda registrar tu dominio en accedeme.com"
|
||||
|
||||
#: admin/wp-accedeme-admin.php:68
|
||||
msgid "Registra tu dominio ahora"
|
||||
msgstr "Registra tu dominio ahora"
|
||||
@@ -0,0 +1,426 @@
|
||||
# Copyright (C) 2020 ZealousWeb Technologies
|
||||
# This file is distributed under the same license as the Accept 2Checkout Payments Using Contact Form 7 plugin.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Accept 2Checkout Payments Using Contact Form 7 1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/accept-2checkout-payments-using-contact-form-7-free\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: 2020-10-21T15:36:36+02:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.4.0\n"
|
||||
"X-Domain: accept-2checkout-payments-using-contact-form-7\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Accept 2Checkout Payments Using Contact Form 7"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "This plugin will integrate 2checkout payment gateway for making your payments through Contact Form 7."
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "ZealousWeb Technologies"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://www.zealousweb.com"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.action.php:81
|
||||
msgid "From Data"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.action.php:82
|
||||
#: inc/admin/class.cf72ch.admin.action.php:329
|
||||
msgid "Do you need help for configuration?"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.action.php:283
|
||||
msgid "Select Forms"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:53
|
||||
msgid "2checkout"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:101
|
||||
#: inc/admin/template/cf72ch.template.php:114
|
||||
msgid "Document Link"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:104
|
||||
msgid "Support Link"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:140
|
||||
msgid "Invoice ID"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:141
|
||||
msgid "Order ID"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:142
|
||||
msgid "Transaction Status"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:143
|
||||
msgid "Total Amount"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/class.cf72ch.admin.filter.php:144
|
||||
msgid "Submitted Date"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:79
|
||||
msgid "Sandbox"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:80
|
||||
msgid "Live"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:113
|
||||
msgid "To use 2Checkout option, first you need to create and save form tags."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:123
|
||||
msgid "Enable/Disable"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:133
|
||||
msgid "Enable Debug Mode"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:143
|
||||
msgid "Payment Mode "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:160
|
||||
msgid "2Checkout Order Item Name *"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:171
|
||||
msgid "Merchant Code "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:182
|
||||
msgid "Secret Key "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:193
|
||||
msgid "Amount Field Name "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:199
|
||||
msgid "Select field name for amount"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:212
|
||||
msgid "Quantity Field Name (Optional)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:218
|
||||
msgid "Select field name for quantity"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:231
|
||||
msgid "Customer Email "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:237
|
||||
msgid "Select field name for customer email"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:251
|
||||
msgid "Select Currency"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:270
|
||||
msgid "Return Success URL (Optional)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:276
|
||||
#: inc/admin/template/cf72ch.template.php:296
|
||||
msgid "Select page"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:290
|
||||
msgid "Return Cancel URL (Optional)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:314
|
||||
msgid "Customer Billing Details"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:323
|
||||
msgid "Billing First Name Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:329
|
||||
msgid "Select field name for billing first name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:342
|
||||
msgid "Billing Last Name Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:348
|
||||
msgid "Select field name for billing last name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:361
|
||||
msgid "Billing Address Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:367
|
||||
msgid "Select field name for billing address"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:380
|
||||
msgid "Billing City Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:386
|
||||
msgid "Select field name for billing city name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:399
|
||||
msgid "Billing State Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:405
|
||||
msgid "Select field name for billing state name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:418
|
||||
msgid "Billing Zipcode Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:424
|
||||
msgid "Select field name for billing Zipcode name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:438
|
||||
msgid "Billing Country Field "
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:444
|
||||
msgid "Select field name for billing country name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:479
|
||||
msgid "<h3>Merchant Code</h3><p>Get Merchant Code from <a href=\"#\" target=\"_blank\">here</a></p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:483
|
||||
msgid "<h3>Order Item Name</h3><p>Set Order Item Name</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:487
|
||||
msgid "<h3>Secret Key</h3><p>Get Secret Key from <a href=\"#\" target=\"_blank\">here</a></p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:491
|
||||
msgid "<h3>Select Currency</h3><p>Select the currency.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:495
|
||||
msgid "<h3>Amount Field</h3><p>Select field from where amount value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:499
|
||||
msgid "<h3>Quantity Field</h3><p>Select field from where quantity value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:503
|
||||
msgid "<h3>Customer Email Field</h3><p>Select field from where customer email value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:507
|
||||
msgid "<h3>Success Return URL Field </h3><p>Select page and redirect customer after succesfully payment done.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:511
|
||||
msgid "<h3>Cancel Return URL Field </h3><p>Select page and redirect customer after cancel payment process or payment not done.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:515
|
||||
msgid "<h3>Billing First Name Field</h3><p>Select field from where billing first name value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:519
|
||||
msgid "<h3>Billing Last Name Field</h3><p>Select field from where billing last name value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:523
|
||||
msgid "<h3>Billing Address Field</h3><p>Select field from where billing address value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:527
|
||||
msgid "<h3>Billing City Field</h3><p>Select field from where billing city value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:531
|
||||
msgid "<h3>Billing State Field</h3><p>Select field from where billing state value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:535
|
||||
msgid "<h3>Billing ZipCode Field</h3><p>Select field from where billing zipcode value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/template/cf72ch.template.php:539
|
||||
msgid "<h3>Billing Country Field</h3><p>Select field from where billing country value needs to be retrieved.</p><p><b>Note: </b> Save the FORM details to view the list of fields.</p>"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:108
|
||||
msgid "<strong><a href=\"https://wordpress.org/plugins/contact-form-7/\" target=\"_blank\">Contact Form 7</a></strong> is required to use <strong>%s</strong>."
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:135
|
||||
#: inc/class.cf72ch.php:136
|
||||
#: inc/class.cf72ch.php:141
|
||||
msgid "2Checkout Payment Details"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:137
|
||||
msgid "Transaction Detail"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:182
|
||||
msgid "2Checkout"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:189
|
||||
msgid "2Checkout Country"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:292
|
||||
msgid "Generate a form-tag for to display 2Checkout payment form"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:301
|
||||
#: inc/class.cf72ch.php:353
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:317
|
||||
#: inc/class.cf72ch.php:368
|
||||
msgid "Insert Tag"
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:324
|
||||
#: inc/class.cf72ch.php:375
|
||||
msgid "To use the value input through this field in a mail field, you need to insert the corresponding mail-tag (%s) into the field on the Mail tab."
|
||||
msgstr ""
|
||||
|
||||
#: inc/class.cf72ch.php:344
|
||||
msgid "Generate a form-tag for to display 2Checkout Country"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:232
|
||||
msgid "2checkout creadit card info not there, please contact admin"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:241
|
||||
msgid "2checkout API credentials are missing"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:249
|
||||
msgid "Account not configured properly, please contact admin"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:599
|
||||
#: inc/lib/class.cf72ch.lib.php:612
|
||||
msgid "Due to Some technical issue, please try again!"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:653
|
||||
msgid "Response :"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:665
|
||||
msgid "Payment Successfully Done."
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:667
|
||||
msgid "Payment is in process from 2 checkout side."
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:672
|
||||
msgid "Transaction Amount :"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:676
|
||||
msgid "Invoice No :"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:680
|
||||
msgid "Payment Status :"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:720
|
||||
#: inc/lib/class.cf72ch.lib.php:1319
|
||||
#: inc/lib/class.cf72ch.lib.php:1353
|
||||
msgid "Card Number"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:723
|
||||
msgid "Expiry Date And Year"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:726
|
||||
#: inc/lib/class.cf72ch.lib.php:1328
|
||||
#: inc/lib/class.cf72ch.lib.php:1384
|
||||
msgid "CVV"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:729
|
||||
msgid "Correct CVV Number"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:732
|
||||
#: inc/lib/class.cf72ch.lib.php:1331
|
||||
#: inc/lib/class.cf72ch.lib.php:1344
|
||||
msgid "Card Holder Name"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:735
|
||||
msgid "Correct Expiry Month And Year"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:793
|
||||
msgid "One or more fields have an error. Please check and try again."
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:801
|
||||
msgid "Please enter amount or valid amount."
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:803
|
||||
msgid "The field is required."
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:1316
|
||||
msgid "Card Verification Number (CVV)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:1322
|
||||
msgid "MM"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:1325
|
||||
msgid "YY"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:1334
|
||||
msgid "Pay via 2Checkout. Accept Credit Cards, Debit Cards"
|
||||
msgstr ""
|
||||
|
||||
#: inc/lib/class.cf72ch.lib.php:1363
|
||||
msgid "Expiration Date"
|
||||
msgstr ""
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user