first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,357 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,74 @@
/**
*
* Prefix everything
* Name descriptively
* Structure radically
*
* CSS Structure
* css/
* ├─ admin/
* │ ├─ base.scss
* │ ├─ layout.scss
* │ ├─ modules/
* │ │ ├─ modal.scss
* │ │ ├─ button.scss
* │ │ ├─ modal.scss
* │ │ ├─ notices.scss
* │ │ ├─ tips-and-tricks.scss
* │ │ ├─ etc.....
* │ ├─ states.scss
* │ ├─ theme.scss
* ├─ admin.scss
* ├─ admin.min.css
* ├─ admin.css
* ├─ variables.scss
*
*/
@import 'variables.scss';
@import 'admin/base.scss';
@import 'admin/layout.scss';
//@import 'admin/modules/modal.scss';
@import 'admin/modules/header.scss';
@import 'admin/modules/dashboard.scss';
@import 'admin/modules/buttons.scss';
@import 'admin/modules/bullets.scss';
@import 'admin/modules/icons.scss';
@import 'admin/modules/badges.scss';
@import 'admin/modules/toast/main.scss';
@import 'admin/modules/onboarding.scss';
@import 'admin/modules/progress.scss';
@import 'admin/modules/ssltest.scss';
@import "admin/modules/placeholder.scss";
@import 'admin/modules/other-plugins.scss';
@import 'admin/modules/tips-tricks.scss';
@import 'admin/modules/wizard.scss';
@import 'admin/modules/wizard/notice.scss';
@import 'admin/modules/wizard/menu.scss';
@import 'admin/modules/wizard/fields.scss';
@import 'admin/modules/wizard/snackbar.scss';
@import 'admin/modules/wizard/mixed-content-scan.scss';
@import 'admin/modules/wizard/learning-mode.scss';
@import 'admin/modules/wizard/letsencrypt.scss';
@import 'admin/modules/wizard/permissions-policy.scss';
@import 'admin/modules/wizard/vulnerabilities.scss';
@import 'admin/modules/notices.scss';
@import 'admin/modules/datatables.scss';
@import 'admin/modules/new-features.scss';
@import 'admin/modules/two-fa.scss';
@import 'admin/modules/introcontainer.scss';
@import "admin/modules/premium_overlay.scss";
//@import 'admin/modules/dark-mode.scss';
//@import 'admin/modules/icons.scss';
@import 'admin/modules/animations.scss';
@import 'admin/modules/tooltip.scss';
//@import 'admin/modules/icons.scss';
//@import 'admin/modules/suggested-plugins.scss';
@import 'admin/states.scss';
@import 'admin/theme.scss';

View File

@@ -0,0 +1,110 @@
.rsssl {
font-variant-numeric: tabular-nums; // https://css-tricks.com/almanac/properties/f/font-variant-numeric/
margin: 0;
margin-left: -20px;
font-size: var(--rsp-fs-300);
box-sizing: border-box;
color: var(--rsp-text-color);
font-weight: 400;
line-height: 1.5;
@media only screen and ( max-width: $rsp-break-xs) {
margin-left: -9px;
}
*, *:before, *:after {
box-sizing: inherit;
}
body, h1, h2, h3, h4, h5, h6, p, ol, ul {
margin: 0;
padding: 0;
}
img {
max-width: 100%;
height: auto;
}
h1, h2, h3, h4, h5, h6 {
color: var(--rsp-text-color);
line-height: 1.5;
}
.rsssl-h0 {
font-size: var(--rsp-fs-900);
font-weight: 700;
letter-spacing: 0.025rem;
}
h1, .rsssl-h1 {
font-size: var(--rsp-fs-800);
line-height: 1.5;
font-weight: 500;
letter-spacing: 0.025rem;
}
h2, .rsssl-h2 {
font-size: var(--rsp-fs-700);
font-weight: 700;
letter-spacing: 0.025rem;
}
h3, .rsssl-h3 {
font-size: var(--rsp-fs-600);
font-weight: 600;
letter-spacing: 0.0125rem;
}
h4, .rsssl-h4 {
font-size: var(--rsp-fs-500);
font-weight: 600;
letter-spacing: 0.0125rem;
}
h5, .rsssl-h5 {
font-size: var(--rsp-fs-400);
font-weight: 400;
letter-spacing: 0.1px;
}
h6, .rsssl-h6 {
font-size: var(--rsp-fs-300);
letter-spacing: 0.1px;
}
p {
color: var(--rsp-text-color);
font-weight: 400;
font-size: var(--rsp-fs-300);
line-height: 1.5;
}
.rsssl-small-text {
font-size: var(--rsp-fs-200);
line-height: 1.5;
color: var(--rsp-text-color-light);
}
a {
font-size: 1em;
}
//wordpress inserts notices after the first h1 or h2. To prevent breaking layout we insert an empty h1 tag at the start of our page, where WP can insert the notice.
.rsssl-notice-hook-element {
display: none !important;
}
.rsssl-divider {
width: 1px;
height: 1.3rem;
background-color: #cccccc;
}
}
// Hide nags from other plugins
.error, .notice, .update-nag, .notice-info {
&:not(.really-simple-plugins) {
display: none !important;
}
&.really-simple-plugins{
margin: var(--rsp-grid-gap);
}
}

View File

@@ -0,0 +1,2 @@
<?php
// Silence is golden.

View File

@@ -0,0 +1,251 @@
/* Grid */
.rsssl {
.rsssl-header, .rsssl-content-area {
max-width: clamp(300px, calc(100% - var(--rsp-grid-gap) * 2), 1600px);
margin: 0 auto;
@media(max-width: $rsp-break-xxl) {
--rsp-grid-gap: var(--rsp-spacing-m);
}
@media(max-width: $rsp-break-xl) { // 1440px
--rsp-grid-gap: var(--rsp-spacing-s);
}
@media(max-width: $rsp-break-l) { // 1366px
--rsp-grid-gap: var(--rsp-spacing-xs);
}
@media(max-width: $rsp-break-m) { // 1280px
}
@media(max-width: $rsp-break-s) { // 1080px
}
}
.rsssl-header-container .rsssl-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
height: 70px;
box-sizing: border-box;
background-color: var(--rsp-background-block-color);
@media(max-width: $rsp-break-s) {
height: 100%;
}
}
.rsssl-logo {
@media(max-width: $rsp-break-xxs) {
display:none;
}
}
.rsssl-header-left {
display: flex;
font-size: var(--rsp-fs-400);
@media(max-width: $rsp-break-s) {
justify-content: center;
margin: var(--rsp-spacing-xs) 0;
order: 3;
width: 100%;
background-color: var(--rsp-background-block-color);
}
.rsssl-header-menu {
margin: auto 15px;
ul {
display: flex;
}
li {
margin-bottom: 0;
}
a {
padding: 23px 15px;
text-decoration: none;
color: var(--rsp-text-color);
height: 100%;
border-bottom: 4px solid transparent;
transition: border 0.3s ease-out;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
@media(max-width: $rsp-break-s) {
padding: 10px 15px;
}
&.active {
border-bottom: 4px solid var(--rsp-brand-primary);
}
&:hover {
color: var(--rsp-brand-primary);
}
}
}
}
.rsssl-header-right {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-left: auto;
gap: var(--rsp-spacing-s);
min-height: 52px;
select {
max-width: 60ch;
}
@media(max-width: $rsp-break-xxs) {
display:none;
}
@media(max-width: $rsp-break-xs) {
.button {
display: none;
}
}
}
.rsssl-content-area {
margin-top: var(--rsp-grid-gap);
}
.rsssl-header-container {
background: var(--rsp-background-block-color);
}
.rsssl-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: max-content;
gap: var(--rsp-grid-gap);
min-height: calc(100vh - 32px - 80px - 20px - var(--rsp-grid-gap)); //32px = wordpress bar, 80px = cmplz bar, 20px = margin-top, 20px is grid gap
&.rsssl-settings, &.rsssl-letsencrypt{
grid-template-columns: minmax(235px, max-content) 2fr minmax(min-content, 1fr);
@media only screen and ( max-width: $rsp-break-s) {
grid-template-columns: repeat(4, 1fr);
.rsssl-wizard-menu, .rsssl-wizard-settings, .rsssl-wizard-help {
grid-column: 1 / -1;
}
}
}
@media only screen and ( max-width: $rsp-break-m) {
grid-template-columns: repeat(2,1fr);
}
@media only screen and ( max-width: $rsp-break-s) {
max-width:790px;
width: calc(100% - var(--rsp-grid-gap) * 2)
}
}
.rsssl-grid-item {
@include rsssl-block;
&.rsssl-disabled {
min-height:320px;//add min height on disabled so the settings is visible behind the locked div.
}
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
flex-direction: column;
flex-basis: 100%;
//min-height: 200px;//seems odd for blocks with only one item: lots of white space
grid-column: span 1;
grid-row: span 1;
&.rsssl-two_fa_users {
.rsssl-grid-item-content {
.rsssl-field-wrap {
margin-top: -50px;
}
}
}
@media(max-width: $rsp-break-s) {
grid-column: span 4;
}
&.no-background {
background: none;
border: none;
box-shadow: none;
}
&.rsssl-column-2 {
grid-column: span 2;
@media(max-width: $rsp-break-s) {
grid-column: span 4;
}
}
&.rsssl-row-2 {
grid-row: span 2;
min-height: 400px;
}
&-header {
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
min-height: calc(30px + var(--rsp-spacing-s) * 2);
@include rsssl-block-padding;
&:empty {
display: none;
}
}
&-title {
margin: 4px 0 4px 0;
}
&-controls {
font-size: var(--rsp-fs-200);
display: flex;
gap: var(--rsp-spacing-s);
}
&-content {
width: 100%;
box-sizing: border-box;
@include rsssl-inline-block-padding;
flex-grow: 100;
&:empty {
display: none;
}
}
&-footer {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: var(--rsp-grid-margin);
width: 100%;
min-height: calc(30px + var(--rsp-spacing-s) * 2);
box-sizing: border-box;
@include rsssl-block-padding;
align-self: flex-end;
.rsssl-legend {
display: flex;
span {
padding-left: 5px;
}
}
&:empty {
display: none;
}
}
.rsssl-flex-push-right {
margin-left: auto;
}
.rsssl-flex-push-left {
margin-right: auto;
}
}
}

View File

@@ -0,0 +1,64 @@
/* Accordeon */
.rsssl-accordeon {
/* Basic styling for the accordion container */
border: 1px solid #ccc;
border-radius: 5px;
overflow: hidden;
transition: all 0.3s ease;
}
.rsssl-accordeon__header {
/* Styling for the accordion header */
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f5f5f5;
padding: 10px;
cursor: pointer;
}
.rsssl-accordeon__header__inner {
/* Styling for the inner container of the header */
display: flex;
align-items: center;
}
.rsssl-accordeon__header__icon {
/* You can set a background-image or other styling here for the icon */
width: 20px;
height: 20px;
margin-right: 10px;
}
.rsssl-accordeon__header__title {
/* Styling for the title text */
font-size: 16px;
font-weight: bold;
}
.rsssl-accordeon__header__button__inner {
/* Styling for the button inside the header */
background: none;
border: none;
cursor: pointer;
font-size: 18px;
}
.rsssl-accordeon__content {
/* By default, hide the content */
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.rsssl-accordeon--open .rsssl-accordeon__content {
/* When the accordion is open, show the content */
max-height: 300px; /* You may need to adjust this value */
}
.rsssl-accordeon__content__inner {
/* Basic styling for the inner content container */
padding: 15px;
background-color: #fff;
}

View File

@@ -0,0 +1,101 @@
.rsssl {
.rsssl-badge {
--badge-height: 20px;
height: var(--badge-height);
line-height: var(--badge-height);
padding-inline: 8px;
min-width: 100px;
text-align: center;
border-radius: var(--rsp-border-radius-xs);
color: var(--rsp-white);
display: table;
margin: auto auto;
font-size: var(--rsp-fs-100);
&.rsp-dark {
background-color: var(--rsp-black);
color: var(--rsp-white);
}
&.rsp-low {
background-color: var(--rsp-yellow-faded);
color: var(--rsp-black);
}
&.rsp-medium {
background-color: var(--rsp-yellow);
color: var(--rsp-black);
}
&.rsp-high {
background-color: var(--rsp-red-faded);
color: var(--rsp-black);
}
&.rsp-critical {
background-color: var(--rsp-red);
color: var(--rsp-white);
}
&.rsp-success {
background-color: var(--rsp-color-success);
color: var(--rsp-white);
}
&.rsp-default {
background-color: var(--rsp-grey-200);
color:black;
}
}
.rsssl-badge-large {
--badge-height: 28px;
height: var(--badge-height);
line-height: var(--badge-height);
padding: 0 10px;
text-align: center;
border-radius: var(--rsp-border-radius-xs);
color: var(--rsp-white);
display: table;
margin: auto auto;
font-size: var(--rsp-fs-300);
font-weight: 400;
&.rsp-dark {
background-color: var(--rsp-black);
color: var(--rsp-white);
}
&.rsp-risk-level-l {
background-color: var(--rsp-yellow-faded);
color: var(--rsp-black);
}
&.rsp-risk-level-m {
background-color: var(--rsp-yellow);
color: var(--rsp-black);
}
&.rsp-risk-level-h {
background-color: var(--rsp-red-faded);
color: var(--rsp-black);
}
&.rsp-risk-level-c {
background-color: var(--rsp-red);
color: var(--rsp-white);
}
&.rsp-success {
background-color: var(--rsp-color-success);
color: var(--rsp-white);
}
&.rsp-default {
background-color: var(--rsp-grey-200);
color:black;
}
}
}

View File

@@ -0,0 +1,61 @@
.rsssl{
// rsssl bullets
.rsssl-bullet {
height: 13px;
width: 13px;
flex: 0 0 13px;
border-radius: 50%;
display: inline-block;
background-color: var(--rsp-grey-300);
&.rsp-yellow {
background-color: var(--rsp-yellow);
}
&.rsp-blue {
background-color: var(--rsp-blue);
}
&.rsp-pink {
background-color: var(--rsp-pink);
}
&.rsp-red, &.rsssl-bullet-error {
background-color: var(--rsp-red);
}
&.rsp-green, &.rsssl-bullet-success {
background-color: var(--rsp-green);
}
&.rsp-blue-yellow {
background: var(--rsp-blue);
background: linear-gradient(77deg, rgba(0,159,255, 1) 0%, rgba(0,159,255, 1) 30%, rgba(244, 191, 62, 1) 70%, rgba(244, 191, 62, 1) 100%);
animation: gradient 2s ease infinite;
background-size: 200% 200%;
}
}
.rsssl-legend{
display: flex;
width: max-content;
color: var(--rsp-text-color-light);
align-items: center;
min-width: 0;
gap: var(--rsp-spacing-xxs);
text-decoration: none;
&:first-of-type{
margin-left: auto;
}
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
}

View File

@@ -0,0 +1,121 @@
.rsssl {
.rsssl-field-button {
button.button {
display:flex;
}
}
a.button, button.button, input.button, span.button {
font-size: var(--rsp-fs-300);
font-weight: 400;
transition: all 0.3s ease;
min-height: 10px;
&.button-secondary, &.button-default {
background: transparent;
}
.rsssl-icon {
padding-top: 7px;
padding-left: 7px;
}
&.button-black {
border: 1px solid var(--rsp-black);
background: var(--rsp-black);
color: var(--rsp-text-color-white);
&:hover, &:focus, &:active {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px var(--rsp-black);
}
}
&.button-tertiary, &.button-red {
border: 0 solid transparent;
background: var(--rsp-red);
color: var(--rsp-text-color-white);
&:hover, &:focus, &:active {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px var(--rsp-red);
background: var(--rsp-red);
color: var(--rsp-text-color-white);
}
}
}
}
.rsssl {
a.rsssl-button-small, button.rsssl-button-small, input.rsssl-button-small {
font-size: var(--rsp-fs-100);
font-weight: 300;
min-height: auto;
}
//on the dashboard, keep a minimum distance between two buttons
.rsssl-button-small + .rsssl-button-small {
margin-left: 10px;
}
}
/* Documents overview */
.rsssl-shortcode {
right: 10000px;
position: absolute;
background-color: #fff;
padding: 0;
white-space: nowrap;
}
.shortcode {
cursor: pointer;
}
.rsssl-action-buttons {
/* Making sure we use the full width of the container */
display: flex;
justify-content: flex-end;
}
.rsssl-action-buttons__inner {
display: flex;
justify-content: flex-end;
}
.rsssl-action-buttons__inner {
//all buttons are floating right
float: right;
}
.rsssl-action-buttons__button {
//add some spacing between the buttons
margin-right: 10px;
}
/* Remove margin for the last button to ensure clean alignment */
.rsssl-action-buttons__inner:last-child {
margin-right: 0;
}
/**
For the mixed content scan we need to do some extra tweaking
*/
.rsssl-mixed-content-scan {
.rsssl-grid-item-content-footer {
margin-left: 0;
margin-right: 0;
padding-left:25px;
.button {
display: block;
margin-right: 0;
margin-left: 0;
}
.components-toggle-control {
margin-top: calc(12px);
}
label {
display: flex;
align-items: center;
justify-content: center;
}
}
}

View File

@@ -0,0 +1,192 @@
.rsssl {
&-grid{
.border-to-border {
.rsssl-grid-item-content {
padding: 0;
& > * {
padding-inline: var(--rsp-spacing-l);
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
}
}
}
.border-to-border.rsssl-ssllabs, .border-to-border.rsssl-wpvul {
.rsssl-grid-item-content {
& > * {
padding-left: 0;
padding-right: 0;
}
}
}
}
.rsssl-wpvul {
.rsssl-icon {
margin-top:5px;
}
}
.rsssl-ssl-labs, .rsssl-hardening {
&-select {
background: var(--rsp-grey-200);
padding-inline: var(--rsp-spacing-l);
padding-block: var(--rsp-spacing-m);
display: grid;
width: 100%;
grid-template-columns: calc(50% - var(--rsp-spacing-s) / 2) calc(50% - var(--rsp-spacing-s) / 2);
gap: var(--rsp-spacing-s);
transition: background-color 0.3s ease-in-out;
&.rsssl-error {
background: var(--rsp-red-faded);
}
&.rsssl-warning {
background: var(--rsp-yellow-faded);
}
&.rsssl-success {
background: var(--rsp-green-faded);
}
&-item {
border-radius: var(--rsp-border-radius-xs);
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
padding-block: var(--rsp-spacing-s);
justify-items: center;
flex-wrap: wrap;
background: var(--rsp-white);
min-height: 118px;
&.active {
box-shadow: inset 0 0 3px 2px var(--rsp-green-faded);
border: 2px solid var(--rsp-green);
}
h2 {
margin-top: var(--rsp-spacing-xxs);
font-weight: 800;
&.big-number{
font-size: var(--rsp-fs-850);
}
}
span {
display: flex;
gap: 3px;
justify-content: center;
font-size: var(--rsp-fs-100);
}
}
}
&-list {
width: 100%;
&-item {
width: 100%;
display: grid;
justify-items: flex-start;
grid-template-columns: auto 1fr auto;
gap: var(--rsp-spacing-s);
padding-block: var(--rsp-spacing-xs);
padding-inline: var(--rsp-spacing-l);
&:nth-of-type(even) {
background: var(--rsp-grey-200);
}
&-text {
width: 100%;
margin-right: auto;
}
&-number {
font-weight: 600;
}
.rsssl-icon{
align-items: start;
margin-top: 2px;
}
}
}
}
.rsssl-ssl-labs {
&-select {
&-item{
padding-inline: var(--rsp-spacing-s);
gap: var(--rsp-spacing-xxs);
}
}
.rsssl-score-snippet {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
height: 18px;
line-height: 18px;
padding-inline: var(--rsp-spacing-xxs);
font-size: var(--rsp-fs-100);
border-radius: var(--rsp-border-radius-xs);
color: var(--rsp-text-color);
text-align: left;
&.rsssl-hover {
height:initial;
//white-space: nowrap;
line-height:initial;
}
&.rsssl-test-inactive {
background-color: var(--rsp-grey-200);
color: var(--rsp-color-disabled);
}
&.rsssl-test-processing {
background-color: var(--rsp-yellow);
color: var(--rsp-black);
}
&.rsssl-test-success {
background-color: var(--rsp-color-success);
color: var(--rsp-text-color-white);
}
&.rsssl-test-error {
background-color: var(--rsp-brand-primary);
color: var(--rsp-black);
}
}
}
.rsssl-hardening {
&-select {
&-item {
.rsssl-badge{
margin-top: var(--rsp-spacing-xxs);
}
}
}
}
}
.rsssl-gridblock-progress-container {
&.rsssl-error {
.rsssl-gridblock-progress {
background: var(--rsp-color-warning);
}
}
&.rsssl-inactive {
height: 4px;
width: 100%;
display: flex;
background: var(--rsp-grey-300);
.rsssl-gridblock-progress {
transition: width 1s ease-in-out;
background: var(--rsp-green);
}
}
}

View File

@@ -0,0 +1,353 @@
.rsssl-field-wrap {
.rdt_TableCol, .rdt_TableCell, .rdt_TableCol_Sortable {
//all text to the left
flex-direction: row;
}
.rdt_TableCol:first-child, .rdt_TableCell:first-child {
min-width: initial;
}
.rdt_TableHeadRow {
.rdt_TableCol:last-child {
flex-grow: 0;
flex-direction: row-reverse;
min-width: initial;
}
}
.rdt_TableRow {
&:nth-child(odd) {
background-color: var(--rsp-grey-200)
}
padding: var(--rsp-spacing-xs) 0;
.rdt_TableCell:last-child {
flex-grow: 0;
}
.rsssl-status-allowed, .rsssl-status-revoked {
min-width: 110px;
margin-right: 10px;
}
}
.rsssl-csp-revoked > div:nth-child(-n+3) {
opacity: 0.3;
}
}
.rsssl-content_security_policy .rsssl-field-wrap {
.rdt_TableHeadRow {
.rdt_TableCol:last-child {
flex-grow: 0;
min-width: initial;
justify-content: flex-end;
}
.rdt_TableCol:nth-last-child(2) {
//flex-direction: row-reverse;
}
}
.rdt_TableRow {
.rsssl-status-allowed, .rsssl-status-revoked, .rsssl-learning-mode-delete {
//margin-right:0;
}
.rdt_TableCell:last-child {
flex-grow: 0;
min-width: initial;
}
.rdt_TableCell:nth-last-child(2) {
//flex-direction: row-reverse;
//margin-right:10px;
}
}
.rsssl-csp-revoked > div:nth-child(-n+3) {
opacity: 0.3;
}
}
//wp-core also adds an svg for the select dropdown, so we hide the one from the react datatables component
nav.rdt_Pagination > div > svg {
display: none !important;
}
.rsssl-content_security_policy, .rsssl-xml_rpc {
.rsssl-field-wrap > div > div {
overflow-x: inherit;
overflow-y: inherit;
}
}
.rsssl-permissions_policy {
.rdt_TableRow {
.rdt_TableCell:last-child {
min-width: fit-content;
.components-input-control__container {
min-width: fit-content;
}
}
}
}
.rsssl-mixed-content-datatable {
& > div > div {
display: flex;
}
}
.rsssl-vulnerabilities_measures {
.rdt_TableRow .rdt_TableCell:nth-child(3) {
max-width: 50%;
}
}
.rsssl-vulnerabilities_overview, .two_fa_users_table, .rsssl-vulnerabilities_measures, .rsssl-limit_login_attempts_country, .rsssl-limit_login_attempts_users, .rsssl-limit_login_attempts_event_log, .rsssl-mixed-content-scan, .rsssl-limit_login_attempts_ip_address, .rsssl-permissions_policy, .rsssl-content_security_policy, .rsssl-two_fa_users, .rsssl-hardening-xml {
.rsssl-field-wrap {
margin-left: CALC(-1 * var(--rsp-spacing-l));
margin-right: CALC(-1 * var(--rsp-spacing-l));
@media(max-width: $rsp-break-m) { // 1280px
margin-left: CALC(-1 * var(--rsp-spacing-m));
margin-right: CALC(-1 * var(--rsp-spacing-m));
}
@media(max-width: $rsp-break-s) { // 1280px
margin-left: CALC(-1 * var(--rsp-spacing-s));
margin-right: CALC(-1 * var(--rsp-spacing-s));
}
//should be s on <1280px
> .components-base-control, .rsssl-comment,
//.rsssl-grid-item-content-footer,
.rsssl-progress-container,
> div > button,
.rsssl-learning-mode-footer,
.rsssl-mixed-content-description,
.rsssl-current-scan-action {
margin-left: var(--rsp-spacing-l);
margin-right: var(--rsp-spacing-l);
}
}
.rdt_TableCell, .rdt_TableCol {
&:first-child {
padding-left: var(--rsp-spacing-l);
padding-right: var(--rsp-spacing-l);
}
&:last-child {
padding-right: var(--rsp-spacing-l);
}
}
}
.rsssl-search-bar {
float: right;
padding: 0;
}
.rsssl-search-bar__inner {
display: flex;
align-items: center;
background-color: gray;
border-radius: 3px;
transition: background-color 0.3s ease;
}
.rsssl-search-bar__inner:focus-within {
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.rsssl-search-bar__icon {
/* Add styles for the search icon */
}
.rsssl-search-bar__input {
border: none;
outline: none;
background: gray;
padding: 3px 5px;
width: 150px; /* Adjust width as needed */
transition: width 0.3s ease;
}
.rsssl-search-bar__input:focus {
width: 200px; /* Adjust width as needed */
}
.rsssl-container {
padding: 2em;
display: flex;
align-items: center;
justify-content: space-between;
}
.rsssl-multiselect-datatable-form {
display: flex;
Justify-content: space-between;
width: 100%;
padding: 1em 2em;
background: var(--rsp-blue-faded);
}
.rdt_TableRow .rdt_TableCell:last-child {
min-width: 20px;
}
.rdt_TableRow .rdt_TableCell:last-child button,
.rdt_TableRow .rdt_TableCell:last-child span {
min-width: 20px;
}
/* Section for EdgeCases and other specific styling */
/* EdgeCase: EventLog */
.rsssl-content_security_policy,
.rsssl-hardening-xml,
.rsssl-vulnerabilities_overview,
.rsssl-limit_login_attempts_ip_address,
.rsssl-limit_login_attempts_users,
.rsssl-limit_login_attempts_country,
.rsssl-limit_login_attempts_event_log {
//first off we remove the min-width from table cell and table col
.rdt_TableCell, .rdt_TableCol {
min-width: initial;
}
.rdt_Pagination {
margin-top: 0;
padding: 0 25px;
}
.rdt_tableCell {
&:has(div > .rsssl-action-buttons) {
position: relative;
}
}
.rsssl-container, .rdt_TableRow {
//Horizontal padding;
// padding: var(--rsp-spacing-m) var(--rsp-spacing-l);
}
.rsssl-field-wrap {
padding: 0;
.rdt_TableHeadRow {
// Somehow the default for the last child is to make it small, well we dont want that.
.rdt_TableCol:last-child {
//we calculate the remaining width of the table and set it to the last column
flex-grow: 1;
}
}
.rdt_TableBody {
.rdt_TableRow {
.rdt_TableCell:last-child {
//we calculate the remaining width of the table and set it to the last column
flex-grow: 1;
}
}
//This is for the Expandable rows in the table
.rdt_Expanding {
.rdt_TableRow {
.rdt_TableCell:first-child {
//we remove all padding
padding: 0;
flex-direction: row;
}
}
}
//This is for the multiselect table
.rdt_TableRow {
.rdt_TableCell:first-child {
//we remove all padding
padding: 0 25px;
flex-direction: row;
}
}
}
.rsssl-learning-mode-delete {
float: right;
}
// in the tableCell we remove all previous styling of the last child
.rdt_TableCell:last-child {
div {
width: 100%;
button,a {
margin-left: 10px;
}
}
}
}
}
/* EdgeCase: CountryTable */
.rsssl-vulnerabilities_measures {
.rdt_TableCell {
&:nth-child(2) {
select {
max-width: 100%;
}
}
}
}
/* EdgeCase: hardening-xml */
.rsssl-hardening-xml {
.rdt_TableCol:first-child {
padding: 0 25px !important;
}
.rdt_TableCell:last-child {
padding: 0 25px !important;
}
.rdt_TableRow .rdt_TableCell:last-child {
flex:1;
display: flex;
justify-content: flex-end;
}
}
/* EdgeCase: Permission_Policy */
.rsssl-content_security_policy,
.rsssl-permissions_policy {
.rdt_TableCol {
&:last-child {
//we calculate the remaining width of the table and set it to the last column
flex-grow: 1;
text-align: right;
div {
width: 100%;
display: flex;
justify-content: flex-start;
}
}
}
.rdt_TableCell {
&:last-child {
//we calculate the remaining width of the table and set it to the last column
flex-grow: 1;
text-align: right;
div {
width: 100%;
display: flex;
justify-content: flex-end;
button {
margin-right: 0px !important;
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
.rsssl-header-container .rsssl-header {
display: flex;
justify-content: space-between;
height: 70px;
box-sizing: border-box;
img {
margin: auto 0;
height: 26px;
}
.rsssl-header-menu {
display: flex;
align-items: center;
height: 100%;
padding: 0 20px;
box-sizing: border-box;
.rsssl-header-menu-item {
display: flex;
align-items: center;
height: 100%;
padding: 0 20px;
box-sizing: border-box;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
&.rsssl-header-menu-item-active {
background-color: #f5f5f5;
}
}
}
.rsssl-header-actions {
display: flex;
align-items: center;
margin-left: auto;
gap: var(--rsp-spacing-s);
select {
max-width: 60ch;
}
}
}

View File

@@ -0,0 +1,29 @@
.rsssl-icon{
display: flex;
align-items: center;
justify-content: center;
> div {
display:flex;
}
svg{
fill: currentColor;
}
&-loading svg{
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
&.rsssl-click-animation{
animation: beat 0.4s ease-out;
}
}
//loaders in buttons
button.button .cmplz-icon.rsssl-icon-loading {
padding-top: 6px;
>div {line-height: inherit;}
}

View File

@@ -0,0 +1,69 @@
.rsssl-modal {
//.rsssl-modal-header, .components-modal__header {
// background-color: var(--rsp-yellow-faded);
// padding: var(--rsp-spacing-m) var(--rsp-spacing-m)!important;
// //no border radius on bottom
// border-bottom-left-radius: 0;
// border-bottom-right-radius: 0;
// border-bottom: 0;
//}
//
//.components-modal__content {
// padding: 0;
// &:before {
// margin-bottom:initial;
// }
//}
//.rsssl-header-extension {
// background-color: var(--rsp-yellow-faded);
// margin: 0;
// padding: 0 var(--rsp-spacing-m);
// p {
// margin: 0;
// padding: var(--rsp-spacing-m) 0;
// padding-top: 0;
// }
//}
.rsssl-intro-logo {
width: 7em;
position: absolute;
right: 1.6em;
height: auto;
bottom: 0.15em;
margin: 0;
padding: 0;
}
@media (max-width: 768px) {
.rsssl-intro-logo {
display:none;
}
}
.rsssl-ssl-intro-container {
.rsssl-details {
display:flex;
padding: var(--rsp-spacing-xs) var(--rsp-spacing-m);
gap: var(--rsp-spacing-xs);
.rsssl-icon {
min-width:25px;
}
}
}
.rsssl-modal-footer {
padding: var(--rsp-spacing-m) var(--rsp-spacing-m);
}
/* spinner for React Icons */
.icon-spin {
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
}

View File

@@ -0,0 +1,135 @@
//.rsssl-modal-backdrop {
// position: fixed;
// top: 0;
// right: 0;
// bottom: 0;
// left: 0;
// background-color: rgba(0, 0, 0, 0.6);
// width: 100%;
// height: 100%;
// z-index: 12; //higher than rsssl-locked
//}
//
//.rsssl-modal {
// width: clamp(300px, 75ch, 100vw - 50px);
// height: max-content;
// position: absolute;
// z-index: 9999;//ensure the modal is over the WP menu in the sidebar.
// border-radius: var(--rsp-border-radius);
// background-color: var(--rsp-white);
// top: 25vh;
// left: -20px;
// right: 0;
// bottom: 0;
// /* transform: translate(-50%, -50%); */
// margin: 25px auto;
//
// &-header {
// @include rsssl-block-padding;
// display: flex;
// justify-content: space-between;
// align-items: center;
// border-radius: var(--rsp-border-radius);
// .modal-title {
// margin: 0;
// }
// .rsssl-modal-close {
// cursor: pointer;
// background: none;
// border: none;
// font-weight: 700;
// }
// button {
// img {
// height: 16px;
// width: 16px;
// }
// }
// }
//
// &-content {
// position: relative;
// font-size: var(--rsp-fs-300);
// line-height: 1.5;
// @include rsssl-block-padding;
// &-subtitle {
// font-size: var(--rsp-fs-600);
// font-weight: 600;
// margin-bottom: var(--rsp-spacing-xs);
// }
// &-description {
// overflow-wrap: anywhere;
// margin-top: 0;
// font-weight: 400;
// line-height: 1.5;
// margin-bottom: var(--rsp-spacing-s);
// }
// }
// &-footer {
// display: flex;
// flex-direction: row;
// @include rsssl-block-padding;
// gap:10px;
// // text-align: right;
// .button {
// display: flex;
// align-items: flex-start;
// justify-content: center;
// min-width: 105px;
//
// //height: 45px;
// //width: 100%;
// text-align: center;
// // margin-right: 20px;
// border-radius: 6px;
// }
//
// .rsssl-button-help {
// background-color: #D7263D;
// color: white;
// border-color: #D7263D;
// &:hover {
// opacity: 0.9;
// }
// }
// }
//}
////this has to apply both to modal and LE activation step
//.rsssl-modal-content-step {
//
// ul{
// margin-bottom: var(--rsp-spacing-m);
// li {
// display: flex;
// align-items: flex-start;
// margin-bottom: var(--rsp-spacing-xxs);
// &.rsssl-is-plugin{
// background-color: var(--rsp-grey-100);
// border: none;
// margin: 10px 0 0 0;
// padding:2px 0;
// position:relative;
// a.button-default.rsssl-read-more{
// position:absolute;
// display:none;
// top:17px;
// right:20px;
// z-index:5;
// @media(max-width: 620px) {
// position:relative;
// margin-left:20px;
// z-index:5;
// }
// }
// }
// .rsssl-icon{
// margin-right:7px;
// }
//
// }
// }
//}
//
//.components-modal__frame {
// width: clamp(300px, 75ch, 100vw - 50px);
//}

View File

@@ -0,0 +1,35 @@
.rsssl{
.rsssl-new-features-block{
.rsssl-grid-item-content{
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
.rsssl-new-features{
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: var(--rsp-spacing-xs);
@media only screen and (max-width: $rsp-break-xxl) and (min-width: $rsp-break-m) {
gap: var(--rsp-spacing-xxs);
}
}
.rsssl-new-feature{
width: 100%;
color: var(--rsp-text-color-light);
display: flex;
align-items: flex-start;
min-width: 0;
gap: var(--rsp-spacing-xs);
text-decoration: none;
.rsssl-icon{
margin-top: 2px;
}
.rsssl-new-feature-desc {
p {
font-size:var(--rsp-fs-300);
}
}
}
}

View File

@@ -0,0 +1,4 @@
/**
Admin notice
*/

View File

@@ -0,0 +1,37 @@
.rsssl-modal.rsssl-onboarding {
width: clamp(300px, 100ch, 100vw );
.rsssl-logo {
height: 26px;
}
.rsssl-modal-content{
display:flex;
.rsssl-onboarding-placeholder {
flex-grow:1
}
&-step {
display:flex;
flex-direction: column;
width:100%;
}
padding-top: var(--rsp-spacing-m);
line-height: 2.2;
min-height:295px;
.rsssl-processing {
opacity:0.5;
}
ul{
li {
.rsssl-icon{
margin-top: 7px;
}
.components-button.is-link {
padding:5px 0;
}
}
}
}
}

View File

@@ -0,0 +1,93 @@
.rsssl {
.rsssl-other-plugins {
.rsssl-placeholder {
background-color:transparent;
}
.rsp-logo img {
height: 20px;
}
}
.rsssl-other-plugins-container {
display: flex !important;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 10px;
font-size: var(--rsp-fs-300);
line-height: 1.7;
gap: var(--rsp-spacing-xxs);
@media screen and (max-width: 992px) {
flex-direction: row;
overflow: hidden;
}
.rsssl-other-plugins-element {
width: 100%;
display: flex;
align-content: space-between;
justify-content: space-between;
gap: 10px;
--rsp-other-plugins-color: var(---rsp-brand-primary);
&.rsssl-zip-recipes {
--rsp-other-plugins-color: var(--rsp-pink);
}
&.rsssl-burst-statistics {
--rsp-other-plugins-color: var(--rsp-green);
}
&.rsssl-complianz-gdpr {
--rsp-other-plugins-color: var(--rsp-blue);
}
&.rsssl-complianz-terms-conditions {
--rsp-other-plugins-color: var(--rsp-black);
}
&.rsssl-really-simple-ssl {
--rsp-other-plugins-color: var(--rsp-yellow);
}
a {
width: max-content;
color: var(--rsp-text-color-light);
transition: color 0.3s ease;
display: flex;
align-items: center;
min-width: 0;
gap: var(--rsp-spacing-xs);
text-decoration: none;
&:hover {
color: var(--rsp-other-plugins-color);
text-decoration: underline;
.rsssl-bullet {
background-color: var(--rsp-other-plugins-color);
}
.rsssl-other-plugins-content {
text-decoration: underline;
}
}
}
.rsssl-bullet {
transition: background-color 0.3s ease;
background-color: var(--rsp-other-plugins-color);
}
.rsssl-other-plugins-content {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.rsssl-other-plugin-status {
min-width: fit-content;
}
}
}
}

View File

@@ -0,0 +1,89 @@
@function randomNum($min, $max) {
$rand: random();
$randomNum: $min + floor($rand * (($max - $min) + 1));
@return $randomNum;
}
$base-color: #ddd;
$shine-color: #e8e8e8;
$animation-duration: 1.6s;
@mixin background-gradient {
background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px);
background-size: 600px;
}
.rsssl-datatable-placeholder {
div {
background-color:var(--rsp-grey-300);
height:25px;
&:nth-child(even) {
background-color:#fff;
}
}
}
.rsssl-rest-error-message {
margin:30px;
ul {
list-style:disc;
margin:20px;
}
}
.rsssl-placeholder {
box-sizing: border-box;
width: 100%;
text-align: left;
margin: 0;
padding-bottom: 24px;
color: #1e1e1e;
-moz-font-smoothing: subpixel-antialiased;
-webkit-font-smoothing: subpixel-antialiased;
border-radius: 2px;
flex-grow: 100;
.rsssl-placeholder-line {
float: left;
width: 100%;
height: 16px;
margin-top: 12px;
border-radius: 7px;
&:last-of-type{
margin-bottom: 24px;
}
@include background-gradient;
animation: shine-lines $animation-duration infinite linear;
@for $i from 1 through 20 {
&:nth-of-type( #{$i} ) {
width: ( random(40) + 60 ) * 1%;
}
}
}
.rsssl-placeholder-line ~ .rsssl-placeholder-line {
background-color: #ddd;
}
}
.rsssl-dashboard-placeholder {
&.rsssl-grid-item.rsssl-row-2 {
grid-row: span 1;
}
}
.rsssl-settings-placeholder {
.rsssl-grid-item{
min-height:400px;
}
}
.rsssl-menu-placeholder {
min-height:400px;
}
@keyframes shine-lines {
0% {
background-position:- 400px;
}
100% {
background-position: 220px;
}
}

View File

@@ -0,0 +1,71 @@
.rsssl {
.rsssl-locked {
&.rsssl-locked-premium {
.rsssl-locked-overlay {
top: calc(100% - 190px) !important;
flex-direction: column;
}
}
.rsssl-locked-overlay {
display: flex;
top: calc(100% - 100px) !important;
text-align: left;
margin-bottom: 20px;
padding: 0;
&.rsssl-premium {
top: calc(100% - 190px) !important;
flex-direction: column;
}
.rsssl-locked-header {
width: 100%;
flex-direction: row;
.rsssl-locked-header-title {
font-weight: 600;
color: var(--rsp-blue)
}
.rsssl-locked-header-subtitle {
}
}
.rsssl-locked-content {
flex-direction: row;
width: 100%;
.rsssl-locked-content-text {
}
}
.rsssl-locked-footer {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
// we want the a to be displayed on the left side
a {
position: relative;
float: left !important;
}
}
.rsssl-locked-footer::after {
content: "";
display: table;
clear: both;
}
}
}
//if a field is both disabled, and the group is premium, we don't want a duplicate opacity on the overlay.
.rsssl-disabled .rsssl-field-wrap {
.rsssl-locked {
background:transparent;
}
}
}

View File

@@ -0,0 +1,257 @@
.rsssl-grid-item.rsssl-progress {
.rsssl-grid-item-content {
padding: 0;
}
.rsssl-placeholder {
@include rsssl-block-padding;
}
}
.rsssl-progress-block {
.rsssl-progress {
overflow: hidden;
height: 20px;
border-radius: 5px;
background-color: #f7f7f7;
.rsssl-bar {
height: 100%;
background-color: var(--rsp-color-success);
transition: width 1s ease;
&.rsssl-orange {
background-color: var(--rsp-color-warning);
}
}
}
.rsssl-progress-bar {
@include rsssl-block-padding;
padding-block: 0;
border-radius:5px;
}
.rsssl-progress-text {
display: flex;
align-items: center;
@include rsssl-block-padding;
padding-block: var(--rsp-spacing-s);
justify-content: flex-start;
gap: var(--rsp-spacing-m);
.rsssl-progress-percentage {
font-size: var(--rsp-fs-800);
font-weight: 700;
}
.rsssl-progress-text-span {
font-weight: 500;
font-size: var(--rsp-fs-600);
a {
margin-left: 3px;
}
@media only screen and (max-width: $rsp-break-l) and (min-width: $rsp-break-m) {
font-size: var(--rsp-fs-500);
}
}
}
}
.rsssl-header-html {
display: flex;
color: var(--rsp-text-color-light);
.rsssl-toggle-active {
text-decoration: underline;
}
}
.rsssl-task-switcher-container {
display: flex;
border-radius: var(--rsp-border-radius);
.rsssl-task-switcher {
&:first-of-type {
border-right: 1px solid var(--rsp-grey-400);
padding-right: 10px;
}
&:last-of-type {
padding-left: 10px;
}
}
}
.rsssl-task-switcher {
font-size: var(--rsp-fs-200);
cursor: pointer;
transition: 0.3s;
&:hover {
text-decoration: underline;
}
}
.rsssl-active-filter-remaining .rsssl-remaining-tasks, .rsssl-active-filter-all .rsssl-all-tasks {
text-decoration: underline;
}
/**
* Task element, list of tasks
*/
.rsssl-task-element {
display: flex;
align-items: flex-start;
justify-content: center;
gap: var(--rsp-spacing-m);
padding-bottom: var(--rsp-spacing-s);
@media(max-width: $rsp-break-m) {
gap: var(--rsp-spacing-xs);
}
.rsssl-task-message {
flex: 1;
font-size: var(--rsp-fs-300);
}
.rsssl-task-form {
margin-top: var(--rsp-spacing-xxs);
display: flex;
gap: var(--rsp-spacing-xs);
}
.rsssl-task-enable {
cursor: pointer;
line-height: 1.5;
}
.rsssl-task-dismiss {
&:hover {
transform: scale(1.1);
}
button {
all: initial; //remove default button styles
cursor: pointer;
padding: 4px;
}
svg {
height: 12px;
width: 12px;
}
}
}
.rsssl-scroll-container {
@include rsssl-block-padding;
//--rsp-scroll-bg-clr: var(--rsp-white);
height: 230px;
overflow-y: auto;
padding-block: 0;
padding-top: var(--rsp-spacing-s);
border-radius: 0;
//background-image: linear-gradient(to top, var(--rsp-scroll-bg-clr), var(--rsp-scroll-bg-clr)),
//linear-gradient(to top, var(--rsp-scroll-bg-clr), var(--rsp-scroll-bg-clr)),
//linear-gradient(to top, rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0)),
//linear-gradient(to bottom, rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0));
//background-position: bottom center, top center, bottom center, top center;
//background-color: var(--rsp-scroll-bg-clr);
//background-repeat: no-repeat;
//background-size: 100% 25px, 100% 25px, 100% 15px, 100% 15px;
//background-attachment: local, local, scroll, scroll;
&::-webkit-scrollbar-track {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0);
background-color: transparent;
}
&::-webkit-scrollbar {
width: 8px;
border-radius: 10px;
background-color: var(--rsp-grey-300);
}
&::-webkit-scrollbar-thumb {
background-color: var(--rsp-grey-400);
border-radius: 10px;
}
}
.rsssl-progress-status-container {
margin-right: 40px;
}
.rsssl-task-status {
display: block;
min-width: 100px;
text-align: center;
border-radius: var(--rsp-border-radius-xs);
padding: 4px 8px;
font-size: var(--rsp-fs-100);
font-weight: 600;
@media(max-width: $rsp-break-m) {
min-width: 80px;
}
&.rsssl-completed, &.rsssl-success {
background-color: var(--rsp-color-success);
color: var(--rsp-text-color-white);
}
&.rsssl-open {
background-color: var(--rsp-color-open);
}
&.rsssl-warning {
background-color: var(--rsp-color-error);
color: var(--rsp-text-color-white);
}
&.rsssl-premium {
background-color: var(--rsp-blue);
color: var(--rsp-text-color-white);
}
&.rsssl-loading {
background-color: var(--rsp-grey-200);
}
}
.rsssl-scroll-container .rsssl-task-status{
@media(max-width: $rsp-break-s) {
aspect-ratio: 1 / 1;
min-width: 10px;
height: 16px;
border-radius: 100%;
text-indent: -9999px; /* sends the text off-screen */
white-space: nowrap;
}
}
.rsssl-plusone {
min-width: 15px;
height: 16px;
font-size: var(--rsp-fs-100);
line-height: 1.5;
display: inline-block;
vertical-align: top;
box-sizing: border-box;
margin: 1px 0 -1px 2px;
padding: 0 5px;
border-radius: 9px;
background-color: #d63638;
color: #fff;
text-align: center;
}
@media only screen and (max-width: $rsp-break-l) {
.rsssl-footer-left {
display:none;
}
}

View File

@@ -0,0 +1,60 @@
.rsssl-tips_tricks{
.rsssl-grid-item-header{
.rsssl-grid-item-controls{
height: 28px;
}
}
}
.rsssl-tips-tricks-container {
display: flex !important;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 10px;
font-size: var(--rsp-fs-300);
line-height: 1.7;
gap: var(--rsp-spacing-xxs);
@media screen and (max-width: 992px) {
flex-direction: row;
overflow: hidden;
}
.rsssl-tips-tricks-element {
width: calc(50% - var(--rsp-spacing-xxs));
@media( max-width: $rsp-break-xs ){
width: 100%;
}
a {
color: var(--rsp-text-color-light);
transition: color 0.3s ease;
display: flex;
align-items: center;
gap: var(--rsp-spacing-xs);
min-width: 0; /* or some value */
text-decoration: none;
&:hover {
color: var(--rsp-brand-primary);
text-decoration: underline;
svg path{
fill: var(--rsp-brand-primary);
}
.rsssl-tips-tricks-content {
text-decoration: underline;
}
}
}
.rsssl-bullet {
transition: background-color 0.3s ease;
background-color: var(--rsp-grey-300);
}
.rsssl-tips-tricks-content {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}

View File

@@ -0,0 +1,27 @@
.#{$rt-namespace}__close-button {
color: #fff;
background: transparent;
outline: none;
border: none;
padding: 0;
cursor: pointer;
opacity: 0.7;
transition: 0.3s ease;
align-self: flex-start;
&--light {
color: #000;
opacity: 0.3;
}
& > svg {
fill: currentColor;
height: 16px;
width: 14px;
}
&:hover,
&:focus {
opacity: 1;
}
}

View File

@@ -0,0 +1,10 @@
.#{$rt-namespace}__spinner {
width: 20px;
height: 20px;
box-sizing: border-box;
border: 2px solid;
border-radius: 100%;
border-color: var(--toastify-spinner-color-empty-area);
border-right-color: var(--toastify-spinner-color);
animation: #{$rt-namespace}__spin 0.65s linear infinite;
}

View File

@@ -0,0 +1,33 @@
@keyframes #{$rt-namespace}__trackProgress {
0% {
transform: scaleX(1);
}
100% {
transform: scaleX(0);
}
}
.#{$rt-namespace}__progress-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
z-index: var(--toastify-z-index);
opacity: 0.7;
transform-origin: left;
&--animated {
animation: #{$rt-namespace}__trackProgress linear 1 forwards;
}
&--controlled {
transition: transform 0.2s;
}
&--rtl {
right: 0;
left: initial;
transform-origin: right;
}
}

View File

@@ -0,0 +1,57 @@
.#{$rt-namespace}__toast {
&-theme--dark {
background: var(--toastify-color-dark);
color: var(--toastify-text-color-dark);
}
&-theme--light {
background: var(--toastify-color-light);
color: var(--toastify-text-color-light);
}
&-theme--colored#{&}--default {
background: var(--toastify-color-light);
color: var(--toastify-text-color-light);
}
&-theme--colored#{&}--info {
color: var(--toastify-text-color-info);
background: var(--toastify-color-info);
}
&-theme--colored#{&}--success {
color: var(--toastify-text-color-success);
background: var(--rsp-green);
}
&-theme--colored#{&}--warning {
color: var(--toastify-text-color-warning);
background: var(--toastify-color-warning);
}
&-theme--colored#{&}--error {
color: var(--toastify-text-color-error);
background: var(--toastify-color-error);
}
}
.#{$rt-namespace}__progress-bar {
&-theme--light {
background: var(--toastify-color-progress-light);
}
&-theme--dark {
background: var(--toastify-color-progress-dark);
}
&--info {
background: var(--toastify-color-progress-info);
}
&--success {
background: var(--toastify-color-progress-success);
}
&--warning {
background: var(--toastify-color-progress-warning);
}
&--error {
background: var(--toastify-color-progress-error);
}
&-theme--colored#{&}--info,
&-theme--colored#{&}--success,
&-theme--colored#{&}--warning,
&-theme--colored#{&}--error {
background: var(--toastify-color-transparent);
}
}

View File

@@ -0,0 +1,60 @@
.#{$rt-namespace}__toast {
position: relative;
min-height: var(--toastify-toast-min-height);
box-sizing: border-box;
margin-bottom: 1rem;
padding: 8px;
border-radius: var(--rsp-border-radius);
border: 1px solid #eeeeee;
box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1), 0 2px 15px 0 rgba(0, 0, 0, 0.05);
box-shadow: var(--rsp-box-shadow);
display: flex;
justify-content: space-between;
max-height: var(--toastify-toast-max-height);
overflow: hidden;
font-family: var(--toastify-font-family);
cursor: default;
direction: ltr;
/* webkit only issue #791 */
z-index: 0;
&--rtl {
direction: rtl;
}
&--close-on-click {
cursor: pointer;
}
&-body {
margin: auto 0;
flex: 1 1 auto;
padding: 6px;
display: flex;
align-items: center;
& > div:last-child {
word-break: break-word;
flex: 1;
}
}
&-icon {
margin-inline-end: 10px;
width: 20px;
flex-shrink: 0;
display: flex;
}
}
.#{$rt-namespace}--animate {
animation-fill-mode: both;
animation-duration: 0.7s;
}
.#{$rt-namespace}--animate-icon {
animation-fill-mode: both;
animation-duration: 0.3s;
}
@media #{$rt-mobile} {
.#{$rt-namespace}__toast {
margin-bottom: 0;
border-radius: 0;
}
}

View File

@@ -0,0 +1,60 @@
.#{$rt-namespace}__toast-container {
z-index: var(--toastify-z-index);
-webkit-transform: translate3d(0, 0, var(--toastify-z-index) px);
position: fixed;
padding: 4px;
width: var(--toastify-toast-width);
box-sizing: border-box;
color: #fff;
&--top-left {
top: 1em;
left: 1em;
}
&--top-center {
top: calc( 2em + 32px);
left: 50%;
transform: translateX(-50%);
}
&--top-right {
top: 1em;
right: 1em;
}
&--bottom-left {
bottom: 1em;
left: 1em;
}
&--bottom-center {
bottom: 1em;
left: 50%;
transform: translateX(-50%);
}
&--bottom-right {
bottom: 1em;
right: 1em;
}
}
@media #{$rt-mobile} {
.#{$rt-namespace}__toast-container {
width: 100vw;
padding: 0;
left: 0;
margin: 0;
&--top-left,
&--top-center,
&--top-right {
top: 0;
transform: translateX(0);
}
&--bottom-left,
&--bottom-center,
&--bottom-right {
bottom: 0;
transform: translateX(0);
}
&--rtl {
right: 0;
left: initial;
}
}
}

View File

@@ -0,0 +1,53 @@
$rt-namespace: 'Toastify';
$rt-mobile: 'only screen and (max-width : 480px)' !default;
:root {
--toastify-color-light: var(--rsp-white);
--toastify-color-dark: var(--rsp-black);
--toastify-color-info: var(--rsp-yellow);
--toastify-color-success: var(--rsp-green);
--toastify-color-warning: var(--rsp-orange);
--toastify-color-error: var(--rsp-red);
--toastify-color-transparent: rgba(255, 255, 255, 0.7);
--toastify-icon-color-info: var(--toastify-color-info);
--toastify-icon-color-success: var(--rsp-green);
--toastify-icon-color-warning: var(--toastify-color-warning);
--toastify-icon-color-error: var(--toastify-color-error);
--toastify-toast-width: 320px;
--toastify-toast-background: #fff;
--toastify-toast-min-height: 42px;
--toastify-toast-max-height: 800px;
--toastify-font-family: sans-serif;
--toastify-z-index: 999999;
--toastify-text-color-light: var(--rsp-text-color);
--toastify-text-color-dark: var(--rsp-text-color-white);
//Used only for colored theme
--toastify-text-color-info: #fff;
--toastify-text-color-success: #fff;
--toastify-text-color-warning: #fff;
--toastify-text-color-error: #fff;
--toastify-spinner-color: #616161;
--toastify-spinner-color-empty-area: #e0e0e0;
// Used when no type is provided
--toastify-color-progress-light: linear-gradient(
to right,
var(--rsp-green),
#5ac8fa,
#007aff,
#34aadc,
#5856d6,
#ff2d55
);
// Used when no type is provided
--toastify-color-progress-dark: #bb86fc;
--toastify-color-progress-info: var(--toastify-color-info);
--toastify-color-progress-success: var(--rsp-green);
--toastify-color-progress-warning: var(--toastify-color-warning);
--toastify-color-progress-error: var(--toastify-color-error);
}

View File

@@ -0,0 +1,197 @@
@mixin timing-function {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
@keyframes #{$rt-namespace}__bounceInRight {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
from {
opacity: 0;
transform: translate3d(3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(-25px, 0, 0);
}
75% {
transform: translate3d(10px, 0, 0);
}
90% {
transform: translate3d(-5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutRight {
20% {
opacity: 1;
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(2000px, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceInLeft {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
0% {
opacity: 0;
transform: translate3d(-3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(25px, 0, 0);
}
75% {
transform: translate3d(-10px, 0, 0);
}
90% {
transform: translate3d(5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutLeft {
20% {
opacity: 1;
transform: translate3d(20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(-2000px, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceInUp {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
from {
opacity: 0;
transform: translate3d(0, 3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
75% {
transform: translate3d(0, 10px, 0);
}
90% {
transform: translate3d(0, -5px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceOutUp {
20% {
transform: translate3d(0, -10px, 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, -2000px, 0);
}
}
@keyframes #{$rt-namespace}__bounceInDown {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutDown {
20% {
transform: translate3d(0, 10px, 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, 2000px, 0);
}
}
.#{$rt-namespace}__bounce-enter {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__bounceInLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__bounceInRight;
}
&--top-center {
animation-name: #{$rt-namespace}__bounceInDown;
}
&--bottom-center {
animation-name: #{$rt-namespace}__bounceInUp;
}
}
.#{$rt-namespace}__bounce-exit {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__bounceOutLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__bounceOutRight;
}
&--top-center {
animation-name: #{$rt-namespace}__bounceOutUp;
}
&--bottom-center {
animation-name: #{$rt-namespace}__bounceOutDown;
}
}

View File

@@ -0,0 +1,43 @@
@keyframes #{$rt-namespace}__flipIn {
from {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
animation-timing-function: ease-in;
}
60% {
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
transform: perspective(400px);
}
}
@keyframes #{$rt-namespace}__flipOut {
from {
transform: perspective(400px);
}
30% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
opacity: 1;
}
to {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0;
}
}
.#{$rt-namespace}__flip-enter {
animation-name: #{$rt-namespace}__flipIn;
}
.#{$rt-namespace}__flip-exit {
animation-name: #{$rt-namespace}__flipOut;
}

View File

@@ -0,0 +1,117 @@
@mixin transform {
transform: translate3d(0, 0, 0);
}
@keyframes #{$rt-namespace}__slideInRight {
from {
transform: translate3d(110%, 0, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInLeft {
from {
transform: translate3d(-110%, 0, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInUp {
from {
transform: translate3d(0, 110%, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInDown {
from {
transform: translate3d(0, -110%, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideOutRight {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(110%, 0, 0);
}
}
@keyframes #{$rt-namespace}__slideOutLeft {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(-110%, 0, 0);
}
}
@keyframes #{$rt-namespace}__slideOutDown {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(0, 500px, 0);
}
}
@keyframes #{$rt-namespace}__slideOutUp {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(0, -500px, 0);
}
}
.#{$rt-namespace}__slide-enter {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__slideInLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__slideInRight;
}
&--top-center {
animation-name: #{$rt-namespace}__slideInDown;
}
&--bottom-center {
animation-name: #{$rt-namespace}__slideInUp;
}
}
.#{$rt-namespace}__slide-exit {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__slideOutLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__slideOutRight;
}
&--top-center {
animation-name: #{$rt-namespace}__slideOutUp;
}
&--bottom-center {
animation-name: #{$rt-namespace}__slideOutDown;
}
}

View File

@@ -0,0 +1,8 @@
@keyframes #{$rt-namespace}__spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,30 @@
@keyframes #{$rt-namespace}__zoomIn {
from {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
50% {
opacity: 1;
}
}
@keyframes #{$rt-namespace}__zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
to {
opacity: 0;
}
}
.#{$rt-namespace}__zoom-enter {
animation-name: #{$rt-namespace}__zoomIn;
}
.#{$rt-namespace}__zoom-exit {
animation-name: #{$rt-namespace}__zoomOut;
}

View File

@@ -0,0 +1,16 @@
@charset "UTF-8";
@import 'variables';
@import 'toastContainer';
@import 'toast';
@import 'theme';
@import 'closeButton';
@import 'progressBar';
@import 'icons';
// entrance and exit animations
@import 'animations/bounce.scss';
@import 'animations/zoom.scss';
@import 'animations/flip.scss';
@import 'animations/slide.scss';
@import 'animations/spin.scss';

View File

@@ -0,0 +1,16 @@
@charset "UTF-8";
@import 'variables';
@keyframes #{$rt-namespace}__trackProgress {
0% {
transform: scaleX(1);
}
100% {
transform: scaleX(0);
}
}
.#{$rt-namespace}__progress-bar {
animation: #{$rt-namespace}__trackProgress linear 1 forwards;
}

View File

@@ -0,0 +1,20 @@
.rsssl div[class^=rsssl-wizard-] {
.rsssl-tooltip-icon .react-tooltip {
max-width:300px;
white-space: pre-wrap;
}
.rsssl-field-wrap {
label {
display: flex;
.cmplz-label-text {
margin-right: 10px;
}
}
.rsssl-icon {
cursor: pointer;
}
}
}

View File

@@ -0,0 +1,21 @@
a.rsssl-skip-link {
display: flex;
justify-content: center;
margin: 15px 0 20px;
}
.rsssl-two_fa_users div[data-column-id="4"].rdt_TableCol {
display: none;
}
.rsssl-two_fa_users .rdt_TableRow .rdt_TableCell:last-child {
flex: 1;
display: flex;
justify-content: flex-end;
}
.rsssl-two_fa_users .rdt_TableHeadRow .rdt_TableCol:last-child {
flex-grow: 1;
display: flex;
justify-content: flex-end;
}

View File

@@ -0,0 +1,162 @@
.rsssl {
div[class^="rsssl-wizard-"] { // starts with selector
.rsssl-helplink {
color: var(--rsp-text-color);
}
.rsssl-grid-item {
position: relative; //to ensure the rsssl-lock stays within the div
margin-bottom: var(--rsp-grid-gap);
@media(max-width: $rsp-break-s) {
grid-column: span 4;
}
}
&.rsssl-column-2{
grid-column: span 2;
@media(max-width: $rsp-break-s) {
grid-column: span 4;
}
}
.rsssl-locked {
position: absolute;
z-index: 10;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(255, 255, 255, 0.8);
border-radius: var(--rsp-border-radius);
.rsssl-shield-overlay {
height: 0;
top: calc(100% - 190px);
position: relative;
align-items: center;
justify-content: center;
display: flex;
}
.rsssl-locked-overlay {
z-index: 1;
top: calc(100% - 110px);
position: relative;
display: flex;
align-items: center;
gap: var(--rsp-spacing-s);
background-color: var(--rsp-white);
@include rsssl-block-padding;
border-radius: var(--rsp-border-radius-input);
margin: var(--rsp-spacing-s);
box-shadow: var(--rsp-box-shadow);
.rsssl-open {
float: left;
margin-right: 12px;
}
.rsssl-progress-status {
float: left;
margin-right: 20px;
}
}
}
//.rsssl-grid-item-footer {
// justify-content: flex-end;
// padding: 0;
// display: flex;
// flex-wrap: wrap;
// align-items: center;
// gap: var(--rsp-grid-margin);
// width: 100%;
// min-height: 20px;
// box-sizing: border-box;
// align-self: flex-end;
//
// .rsssl-legend {
// display: flex;
// span {
// padding-left: 5px;
// }
// }
//
// &:empty {
// display: none;
// }
//}
& > div:nth-last-of-type(2) {
margin-bottom: 0;
border-radius: var(--rsp-border-radius) var(--rsp-border-radius) 0 0;
}
.rsssl-grid-item-footer-container {
position: sticky;
bottom: 0;
display: flex;
flex-direction: column;
z-index: 12; //should be above 10, for the text editor, which has 10.
.rsssl-grid-item-footer-buttons {
a.button, button {
box-shadow: none !important;
&:focus, &:active {
box-shadow: none !important;
}
}
}
}
.rsssl-grid-item-footer-scroll-progress-container {
display: flex;
flex-direction: column;
width: 100%;
height: 3px;
background-color: var(--rsp-grey-300);
overflow: hidden;
}
.rsssl-grid-item-footer-scroll-progress {
height: 100%;
background-color: var(--rsp-blue);
}
.rsssl-grid-item-footer {
background: var(--rsp-grey-100);
@include rsssl-block-padding();
box-shadow: var(--rsp-box-shadow);
border-radius: 0 0 var(--rsp-border-radius) var(--rsp-border-radius);
border-top: 1px solid var(--rsp-grey-300);
box-sizing: border-box;
align-items: center;
gap: var(--rsp-grid-margin);
width: 100%;
min-height: 20px;
justify-content: space-around;
// last item within the footer
& > div:last-of-type {
margin-left: auto;
}
&-buttons{
display: flex;
justify-content: flex-end;
align-items: center;
gap: var(--rsp-spacing-s);
}
.rsssl-legend {
display: flex;
span {
padding-left: 5px;
}
}
&-upsell-bar {
.button {
display:inline-block !important;
}
}
&:empty {
display: none;
}
}
}
}

View File

@@ -0,0 +1,176 @@
html {
scroll-behavior: smooth;
}
.rsssl{
div[class^="rsssl-wizard-"]{ // starts with selector
.components-flex{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.components-flex-item label{
margin: 0;
}
.rsssl-tooltip {
flex-grow:1;
}
.components-input-control__container {
max-width: max-content;
}
}
.rsssl-grid-item-content label{
font-size: var(--rsp-fs-300);
font-weight: 400;
line-height: 1.5;
text-transform: unset;
box-sizing: border-box;
display: inherit;
max-width: 100%;
//z-index: 1; => this conflicts with the tooltip z-index
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.components-base-control__field{
margin-bottom: 0;
}
.components-toggle-control{
.components-base-control__field, .components-flex{
display: flex;
flex-direction: row-reverse;
align-items: center;
justify-content: space-between;
width:100%;
.components-form-toggle{
margin-right: 0;
}
}
}
select option {
font-size: var(--rsp-fs-300);
}
.components-form-toggle.is-checked .components-form-toggle__track{
background-color: var(--rsp-dark-blue);
}
input.components-form-toggle__input[type=checkbox]:disabled, {
background: var(--rsp-grey-100);
opacity:0.7
}
.rsssl-grid-item{
.rsssl-grid-item-content{
padding: var(--rsp-spacing-xs) 0;
}
}
.rsssl-field-wrap {
.rsssl-comment {
font-style:italic;
}
}
.rsssl-field-wrap, .rsssl-settings-block-intro{
padding-block: var(--rsp-spacing-s);
@include rsssl-inline-block-padding;
overflow: hidden;
& > .rsssl-field-wrap{
padding: 0;
}
}
.rsssl-field-button{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
}
}
.rsssl-highlight {
background-color: transparent;
border-left: 4px solid var(--rsp-green);
-o-animation: fadeIt 3s ease-in-out;
animation: fadeIt 3s ease-in-out;
scroll-margin-top: 100px;
scroll-padding-top:100px;
}
@-o-keyframes fadeIt {
0% { background-color: transparent; }
30% { background-color: var(--rsp-green-faded); }
100% {
border-right: 0;
background-color: inherit;
}
}
@keyframes fadeIt {
0% {
background-color: transparent;
border-right: 0;
}
30% { background-color: var(--rsp-green-faded); }
100% { background-color: inherit; }
}
}
.rsssl-email-verified {
position: absolute;
bottom: 23px;
right: 35px;
}
//switch padding to top, to prevent tasks from getting stuck to text field
.rsssl-license {
.rsssl-task-element {
padding-top: var(--rsp-spacing-s);
padding-bottom: 0;
}
.rsssl-license-field{
display:flex;
}
}
.input-container {
position: relative;
display: inline-block;
width: 100%;
}
input.rsssl-input {
&.full {
width: 100%;
padding-right: 40px;
}
&.rsssl-error {
border: 2px solid var(--rsp-red);
outline: none;
&:focus {
border-color: var(--rsp-red) !important;
}
}
&.rsssl-success {
border: 2px solid var(--rsp-green);
outline: none;
&:focus {
border-color: var(--rsp-green) !important;
}
}
}
.wp-core-ui select {
/* Your styles here */
flex-grow: 1 !important;
max-width: 33%;
}
.icon-button {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
border: none;
background: none;
cursor: pointer;
}
.rsssl-group-filter {
min-width: 25%;
max-width: 100%!important;
}

View File

@@ -0,0 +1,60 @@
.rsssl-learningmode-placeholder {
height:150px;
div {
background-color:var(--rsp-grey-200);
margin:10px 0;
height:20px;
}
}
.rsssl-learning-mode-delete {
cursor: pointer;
background: none;
border: none;
font-size: 1.5em;
font-weight: 700;
}
.rsssl-locked-overlay {
.rsssl-open {
float: left;
margin-right: 12px;
}
.rsssl-progress-status {
@extend .rsssl-task-status;
&.rsssl-learning-mode-completed, &.rsssl-learning-mode-enforced {
background-color: var(--rsp-color-success);
color:#fff;
}
&.rsssl-learning-mode {
background-color: var(--rsp-color-open);
}
&.rsssl-learning-mode-error {
background-color: var(--rsp-color-error);
color:#fff;
}
&.rsssl-disabled, &.rsssl-learning-mode-disabled {
background-color: var(--rsp-color-disabled);
}
}
}
.rsssl-learning-mode-footer {
display:flex;
align-items: center;
justify-content: flex-start;
gap: var(--rsp-spacing-s);
select {
margin-left:auto;
}
label {
display: flex;
align-items: center;
input{
margin-top: 0;
}
}
}

View File

@@ -0,0 +1,108 @@
.rsssl-lets-encrypt-tests {
margin:var(--rsp-spacing-xs) var(--rsp-spacing-xl);
.rsssl-progress-bar {
padding-block: 0;
margin-bottom:var(--rsp-spacing-m);
.rsssl-progress {
overflow: hidden;
height: var(--rsp-spacing-m);
border-radius: 5px;
background-color: var(--rsp-grey-200);
.rsssl-bar {
height: 100%;
background-color: var(--rsp-color-success);
&.rsssl-orange {
background-color: var(--rsp-color-warning);
}
}
}
}
p {
margin-bottom:var(--rsp-spacing-m);
}
.rsssl-progress-text {
display: flex;
align-items: center;
@include rsssl-block-padding;
padding-block: 0;
padding-top: var(--rsp-spacing-xs);
.rsssl-progress-percentage {
font-size: 32px;
font-weight: 700;
}
.rsssl-progress-text-span {
margin-left: 35px;
font-size: 18px;
font-weight: 600;
a {
margin-left: 3px;
}
}
}
ul {
li {
display:flex;
margin-bottom:15px;
.rsssl-icon {
margin-right:7px;
}
/*Nested li */
ul li:before {
background-color: var(--rsp-grey-500);
color: #fff;
height: 6px;
width: 6px;
border-radius: 50%;
content: '';
position: absolute;
margin-top: 7px;
margin-left: -19px;
}
}
}
.rsssl-test-results {
ul {
li {
display:block;
}
}
h4 {
margin:var(--rsp-spacing-m) 0;
}
a+button {
margin-left:var(--rsp-spacing-m);
}
.rsssl-certificate-data {
display:none;
}
.rsssl-dns-text-records {
div {
display:flex;
flex-direction: row;
margin-right:20px;
.rsssl-dns-domain, .rsssl-dns-field {
margin-right:var(--rsp-spacing-m);
width: 50%;
}
}
}
}
.rsssl-modal-subtitle {
display:none;
}
.components-toggle-control {
margin: 20px 0;
}
}

View File

@@ -0,0 +1,158 @@
.rsssl-wizard-menu{
height: fit-content;
background: none !important;
box-shadow: none !important;
.rsssl-grid-item-header {
padding-left: var(--rsp-spacing-xs);
}
.rsssl-grid-item-content{
padding: 0;
padding-bottom: var(--rsp-spacing-l);
}
}
.rsssl-wizard-menu-items > .rsssl-menu-item > a {
font-weight: 600 !important;
padding-inline: var(--rsp-spacing-xs) !important;
}
.rsssl-wizard-menu-items {
.rsssl-main-menu {
.rsssl-active {
border-radius: var(--rsp-border-radius-s);
background: var(--rsp-yellow-faded);
box-shadow: var(--rsp-box-shadow);
a:hover {
text-decoration: none;
}
}
.rsssl-menu-item {
a {
span {
font-weight: 600;
}
}
}
}
.rsssl-menu-item{
a{
display: flex;
align-items: center;
gap: var(--rsp-spacing-xs);
text-decoration: none;
color: var(--rsp-text-color);
font-size: var(--rsp-fs-400);
padding-block: var(--rsp-spacing-xs);
transition: all 0.2s ease-in-out;
padding-left: var(--rsp-spacing-xs);
&:hover {
text-decoration: underline;
}
}
&.rsssl-active{
> a{
font-weight: 600;
}
a {
&:focus {
box-shadow: none !important;
}
}
}
&.rsssl-featured{
&.rsssl-active {
.rsssl-menu-item-beta-pill {
color: var(--rsp-dark-blue);
}
}
a{
flex-wrap: wrap;
.rsssl-menu-item-featured-pill{
background: var(--rsp-green);
color: var(--rsp-text-color-white);
padding: 4px 8px;
border-radius: var(--rsp-border-radius-xs);
font-size: var(--rsp-fs-100);
}
.rsssl-menu-item-beta-pill{
color: var(--rsp-dark-blue);
}
}
}
&.rsssl-new{
.rsssl-menu-item-new-pill{
background: var(--rsp-yellow);
color: var(--rsp-text-color-dark);
padding: 4px 8px;
border-radius: var(--rsp-border-radius-xs);
font-size: var(--rsp-fs-100);
}
&.rsssl-active {
.rsssl-menu-item-new-pill {
color: var(--rsp-text-color-dark);
}
}
a{
flex-wrap: wrap;
}
}
&.rsssl-premium{
a{
flex-wrap: wrap;
.rsssl-menu-item-featured-pill{
background: var(--rsp-dark-blue);
color: var(--rsp-text-color-white);
padding: 2px 9px;
border-radius: var(--rsp-border-radius);
font-size: var(--rsp-fs-100);
}
}
}
}
.rsssl-premium-menu-item {
background: var(--rsp-dark-blue-faded);
div {
display: flex;
align-items: center;
gap: var(--rsp-spacing-xs);
text-decoration: none;
color: var(--rsp-text-color);
font-size: var(--rsp-fs-400);
padding-block: var(--rsp-spacing-xs);
@include rsssl-inline-block-padding;
transition: all 0.2s ease-in-out;
border-left: 4px solid transparent;
}
}
.rsssl-submenu-item{
a{
padding-left: calc(var(--rsp-spacing-xs) + var(--rsp-spacing-s)) !important;
font-size: var(--rsp-fs-300);
}
.rsssl-active {
a {
text-decoration: none;
position: relative;
span {
color: initial;
}
&::before {
content: '\2022';
color: var(--rsp-dark-blue);
font-size: 3em;
position: absolute;
left: var(--rsp-spacing-xxs) !important;
margin-bottom: 7px;
}
}
}
}
}

View File

@@ -0,0 +1,53 @@
.rsssl-mixed-content-scan {
.rsssl-mixed-content-placeholder {
height:250px;
div {
background-color:var(--rsp-grey-200);
margin:10px 0;
height:20px;
}
}
.rsssl-shield-overlay {
height:250px;
align-items: center;
justify-content: center;
display:flex;
}
.rsssl-field-wrap {
.rdt_TableCell[data-column-id="2"] {
display:grid;
}
.rdt_TableCol, .rdt_TableCell {
min-width: 110px;
}
}
.rsssl-progress-container {
.rsssl-progress-bar {
border-radius:5px;
height:20px;
background-color:var(--rsp-green);
}
}
.rsssl-task-status{
min-width: min-content;
&.rsssl-warning {
background-color: var(--rsp-yellow);
color: var(--rsp-text-color);
}
}
button.button{
line-height: 1.5;
min-height: 10px;
}
.rsssl-grid-item-content-footer{
display: flex;
gap: var(--rsp-spacing-s);
}
.rsssl-current-scan-action, .rsssl-mixed-content-description {
margin:10px 5px;
font-size: var(--rsp-fs-300);
}
}

View File

@@ -0,0 +1,88 @@
.rsssl-wizard-help {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
gap: var(--rsp-spacing-xs);
details{
font-size: var(--rsp-fs-200);
.rsssl-help-more-info {
display: flex;
flex-direction: row;
margin-top: 12px;
}
summary {
display: grid;
grid-template-columns: 1fr auto;
justify-content: space-between;
font-size: var(--rsp-fs-300);
font-weight: 600;
cursor:pointer;
&::-webkit-details-marker {
display:none;
}
&:first-of-type {
list-style-type: none;
}
.rsssl-icon{
transition: all .3s ease-in-out;
transform: rotate(0deg);
}
}
}
code{
white-space: pre-line;
display: block;
}
summary, p {
font-size: var(--rsp-fs-200);
}
details[open]{
padding: var(--rsp-spacing-s) var(--rsp-spacing-m);
summary{
padding: 0;
padding-bottom: var(--rsp-spacing-xs);
.rsssl-icon{
transform: rotate(180deg);
}
}
}
}
.rsssl-wizard-help {
.rsssl-help-header {
width:100%;
display:flex;
padding:10px;
.rsssl-help-title{
font-size:18px;
}
.rsssl-help-control {
margin-left:auto;
cursor:pointer;
}
}
>div{
flex-grow:1;
width:100%;
}
}
.rsssl-wizard-help-notice {
width: 100%;
@include rsssl-block;
border-radius: var(--rsp-border-radius-s);
height: fit-content;
background-color: var(--rsp-dark-blue-faded);
&.rsssl-warning {
background-color: var(--rsp-red-faded);
}
&.rsssl-open {
background-color: var(--rsp-yellow-faded);
}
summary, p{
padding: var(--rsp-spacing-s) var(--rsp-spacing-m);
}
}

View File

@@ -0,0 +1,10 @@
.rsssl div[class^=rsssl-wizard-] {
.rsssl-permissions_policy {
.rdt_TableCell , .rdt_TableCol{
min-width:fit-content;
}
.rsssl-locked .rsssl-shield-overlay {
top:calc(100% - 300px);
}
}
}

View File

@@ -0,0 +1,18 @@
.rsssl{
.components-snackbar-list.edit-site-notices{
width: max-content;
position: fixed;
bottom: var(--rsp-spacing-m);
right: var(--rsp-spacing-l);
& > div{
margin-left: auto;
}
.components-snackbar{
@include rsssl-block;
color: var(--rsp-color-success);
background-color: #fff;
font-weight:700;
font-size:14px;
}
}
}

View File

@@ -0,0 +1,16 @@
.rsssl-vulnerability-action {
a.button {
margin-left:10px;
}
}
.rsssl-processing {
opacity:0.5;
}
.rsssl-vulnerabilities_measures {
.rsssl-locked-overlay {
input[type=checkbox] {
margin-top: 0;
}
}
}

View File

@@ -0,0 +1,114 @@
.rsssl{
/*skeleton*/
$panelheight : 38px;
$panelborder : 1px;
$paneloffset : 3*($panelborder+$panelheight);
$rows : 6;
.rsssl-skeleton:empty {
margin: auto;
margin-bottom: 25px;
width: 100%;
height: ($rows*$panelheight)+($rows+1)*$panelborder; /* change height to see repeat-y behavior */
background-image:
linear-gradient( 100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5) 70%, rgba(255, 255, 255, 0.5) 15% ),
linear-gradient( #f2f2f2 $panelheight, transparent 0 ),
linear-gradient( #f2f2f2 $panelheight, transparent 0 ),
linear-gradient( #f2f2f2 $panelheight, transparent 0 ),
linear-gradient( #f2f2f2 $panelheight, transparent 0 );
background-repeat: repeat-y;
background-size:
50px 200px, /* highlight */
100% $paneloffset,
100% $paneloffset,
100% $paneloffset,
100% $paneloffset;
background-position:
0 0, /* highlight */
$panelborder $panelborder,
$panelborder $panelheight+(2*$panelborder),
$panelborder (2*$panelheight)+(3*$panelborder),
$panelborder (3*$panelheight)+(4*$panelborder);
background-color:#d6d8db;
border-right: $panelborder solid #d6d8db;
animation: shine 2.5s infinite;
}
@keyframes shine {
to {
background-position:
100% 0, /* move highlight to right */
$panelborder $panelborder,
$panelborder $panelheight+(2*$panelborder),
$panelborder (2*$panelheight)+(3*$panelborder),
$panelborder (3*$panelheight)+(4*$panelborder);
}
}
/*loader*/
.rsssl-loader {
margin: 0;
width: 50px;
height: 15px;
text-align: center;
font-size: 10px;
> div {
margin:1px;
background-color: #333;
height: 100%;
width: 3px;
display: inline-block;
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
animation: sk-stretchdelay 1.2s infinite ease-in-out;
}
&.rsssl-loader-white >div {
background-color: #fff;
}
.rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
.rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
}
.button-primary .rsssl-loader div {
background-color: #fff;
}
@-webkit-keyframes sk-stretchdelay {
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
20% { -webkit-transform: scaleY(1.0) }
}
@keyframes sk-stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
} 20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}
}

View File

@@ -0,0 +1,63 @@
.rsssl{
// Plugin specific variables down here please
--rsp-brand-primary: var(--rsp-yellow);
--rsp-brand-secondary: var(--rsp-blue);
--rsp-brand-primary-faded: var(--rsp-yellow-faded);
}
//@media (prefers-color-scheme: dark) {
// :root {
// // Borders and stuff;
// --rsp-border: 1px solid var(--rsp-border-color);
// --rsp-box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
// --rsp-box-shadow-dark: rgba(0, 0, 0, 0.2) 0px 4px 6px -1px, rgba(0, 0, 0, 0.12) 1px 0px 4px 1px;
// --rsp-border-color: #dfdfdf;
//
// // RSP Brand Colors
// --rsp-black: #333;
// --rsp-white: #fff;
// --rsp-yellow: #f4bf3e;
// --rsp-blue: #009fff;
// --rsp-dark-blue: #1E73BE;
// --rsp-green: #2e8a37;
// --rsp-red: #D7263D;
// --rsp-pink: #E35899;
// --rsp-wp-blue: #007cba;
//
// --rsp-yellow-faded: #f2e6c9;
// --rsp-blue-faded: #ecf8fe;
// --rsp-dark-blue-faded: #ebf2f9;
// --rsp-green-faded: #ecf4ed;
// --rsp-red-faded: #fbebed;
// --rsp-pink-faded: #fceff5;
// --rsp-wp-blue-faded: #c6e0ef;
//
// --rsp-background-block-color: var(--rsp-black);
// --rsp-background-color: var(--rsp-grey-600);
//
// //Input colors
// --rsp-input-background-color: #fff;
// --rsp-input-text-color: var(--rsp-text-color);
// --rsp-input-border-color: var(--rsp-grey-400);
//
// --rsp-text-color: rgba(255, 255, 255, 0.95);
// --rsp-text-color-invert: rgba(26, 26, 26, 0.95);
// --rsp-text-color-white: rgba(255, 255, 255, 0.95);
// --rsp-text-color-light: rgba(69, 69, 82, 0.95);
//
// --rsp-grey-100: #fafafa;
// --rsp-grey-200: #f9f9f9;
// --rsp-grey-300: #ededed;
// --rsp-grey-400: #c6c6c6;
// --rsp-grey-500: #737373;
// --rsp-grey-600: #696969;
//
// // Notification colors
// --rsp-color-success: var(--rsp-green);
// --rsp-color-error: var(--rsp-red);
// --rsp-color-open: var(--rsp-yellow);
// --rsp-color-disabled: var(--rsp-grey-300);
// }
// .rsssl-header .rsssl-logo{
// filter: brightness(0) invert(1);
// }
//}

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

View File

@@ -0,0 +1,122 @@
/*
This was created for styling the plugin overview page for vulnerable plugins.
*/
:root {
--rsp-spacing-xxs: 5px;
--rsp-spacing-xs: 10px;
--rsp-spacing-s: 15px;
--rsp-spacing-m: 20px;
--rsp-spacing-l: 25px;
--rsp-spacing-xl: 30px;
--rsp-grid-margin: var(--rsp-spacing-s);
--rsp-grid-gap: var(--rsp-spacing-m);
--rsp-border-radius: 12px;
--rsp-border-radius-s: 8px;
--rsp-border-radius-xs: 3px;
--rsp-border: 1px solid var(--rsp-border-color);
--rsp-box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
--rsp-box-shadow-dark: rgba(0, 0, 0, 0.2) 0px 4px 6px -1px, rgba(0, 0, 0, 0.12) 1px 0px 4px 1px;
--rsp-border-color: #dfdfdf;
--rsp-black: #333;
--rsp-white: #fff;
--rsp-yellow: #fbc43e;
--rsp-blue: #009fff;
--rsp-dark-yellow: #e6a800;
--rsp-dark-blue: #1E73BE;
--rsp-green: #2e8a37;
--rsp-red: #D7263D;
--rsp-dark-red: #9b0212;
--rsp-pink: #E35899;
--rsp-wp-blue: #007cba;
--rsp-yellow-faded: #fdf4df;
--rsp-blue-faded: #ecf8fe;
--rsp-dark-blue-faded: #ebf2f9;
--rsp-green-faded: #ecf4ed;
--rsp-red-faded: #fbebed;
--rsp-pink-faded: #fceff5;
--rsp-wp-blue-faded: #c6e0ef;
--rsp-background-block-color: var(--rsp-white);
--rsp-background-color: #f0f0f1;
--rsp-input-background-color: #fff;
--rsp-input-text-color: var(--rsp-text-color);
--rsp-input-border-color: var(--rsp-grey-400);
--rsp-text-color: rgba(26, 26, 26, 0.9);
--rsp-text-color-invert: rgba(255, 255, 255, 0.9);
--rsp-text-color-white: rgba(255, 255, 255, 0.9);
--rsp-text-color-light: rgba(69, 69, 82, 0.9);
--rsp-text-color-hover: var(--rsp-green);
--rsp-grey-100: #fafafa;
--rsp-grey-200: #f7f7f7;
--rsp-grey-300: #ededed;
--rsp-grey-400: #c6c6c6;
--rsp-grey-500: #737373;
--rsp-grey-600: #696969;
--rsp-color-success: var(--rsp-green);
--rsp-color-error: var(--rsp-red);
--rsp-color-warning: var(--rsp-yellow);
--rsp-color-open: var(--rsp-yellow);
--rsp-color-disabled: var(--rsp-grey-300);
--rsp-fs-100: 0.6875rem;
--rsp-fs-200: 0.75rem;
--rsp-fs-300: 0.8125rem;
--rsp-fs-400: 0.875rem;
--rsp-fs-500: 1rem;
--rsp-fs-600: 1.125rem;
--rsp-fs-700: 1.25rem;
--rsp-fs-800: 1.5rem;
--rsp-fs-850: 2.8rem;
--rsp-fs-900: 3.5rem;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.rsssl-btn-vulnerable {
display: inline-block;
text-decoration: none;
font-size: var(--rsp-fs-100);
line-height: 2.15384615;
min-height: 30px;
margin: 0;
padding: 4px 8px;
min-width: 100px;
text-align: center;
cursor: pointer;
font-weight: 600;
-webkit-appearance: none;
border-radius: var(--rsp-border-radius-xs);
white-space: nowrap;
box-sizing: border-box;
background-color: var(--rsp-yellow);
color: var(--rsp-black);
border-color: var(--rsp-yellow);
}
.rsssl-btn-vulnerable:hover {
text-decoration: underline;
}
.rsssl-btn-vulnerable.rsssl-critical {
background-color: var(--rsp-red);
color: var(--rsp-white);
border-color: var(--rsp-red);
}
.rsssl-btn-vulnerable.rsssl-high {
background-color: var(--rsp-red);
color: var(--rsp-white);
border-color: var(--rsp-red);
}
.rsssl-btn-vulnerable.rsssl-medium {
border-color: var(--rsp-yellow);
color: var(--rsp-black);
background-color: var(--rsp-yellow);
}

View File

@@ -0,0 +1 @@
:root{--rsp-spacing-xxs:5px;--rsp-spacing-xs:10px;--rsp-spacing-s:15px;--rsp-spacing-m:20px;--rsp-spacing-l:25px;--rsp-spacing-xl:30px;--rsp-grid-margin:var(--rsp-spacing-s);--rsp-grid-gap:var(--rsp-spacing-m);--rsp-border-radius:12px;--rsp-border-radius-s:8px;--rsp-border-radius-xs:3px;--rsp-border:1px solid var(--rsp-border-color);--rsp-box-shadow:rgba(0,0,0,0.1) 0 4px 6px -1px,rgba(0,0,0,0.06) 0 2px 4px -1px;--rsp-box-shadow-dark:rgba(0,0,0,0.2) 0 4px 6px -1px,rgba(0,0,0,0.12) 1px 0 4px 1px;--rsp-border-color:#dfdfdf;--rsp-black:#333;--rsp-white:#fff;--rsp-yellow:#fbc43e;--rsp-blue:#009fff;--rsp-dark-yellow:#e6a800;--rsp-dark-blue:#1e73be;--rsp-green:#2e8a37;--rsp-red:#d7263d;--rsp-dark-red:#9b0212;--rsp-pink:#e35899;--rsp-wp-blue:#007cba;--rsp-yellow-faded:#fdf4df;--rsp-blue-faded:#ecf8fe;--rsp-dark-blue-faded:#ebf2f9;--rsp-green-faded:#ecf4ed;--rsp-red-faded:#fbebed;--rsp-pink-faded:#fceff5;--rsp-wp-blue-faded:#c6e0ef;--rsp-background-block-color:var(--rsp-white);--rsp-background-color:#f0f0f1;--rsp-input-background-color:#fff;--rsp-input-text-color:var(--rsp-text-color);--rsp-input-border-color:var(--rsp-grey-400);--rsp-text-color:rgba(26,26,26,0.9);--rsp-text-color-invert:rgba(255,255,255,0.9);--rsp-text-color-white:rgba(255,255,255,0.9);--rsp-text-color-light:rgba(69,69,82,0.9);--rsp-text-color-hover:var(--rsp-green);--rsp-grey-100:#fafafa;--rsp-grey-200:#f7f7f7;--rsp-grey-300:#ededed;--rsp-grey-400:#c6c6c6;--rsp-grey-500:#737373;--rsp-grey-600:#696969;--rsp-color-success:var(--rsp-green);--rsp-color-error:var(--rsp-red);--rsp-color-warning:var(--rsp-yellow);--rsp-color-open:var(--rsp-yellow);--rsp-color-disabled:var(--rsp-grey-300);--rsp-fs-100:.6875rem;--rsp-fs-200:.75rem;--rsp-fs-300:.8125rem;--rsp-fs-400:.875rem;--rsp-fs-500:1rem;--rsp-fs-600:1.125rem;--rsp-fs-700:1.25rem;--rsp-fs-800:1.5rem;--rsp-fs-850:2.8rem;--rsp-fs-900:3.5rem}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}.rsssl-btn-vulnerable{display:inline-block;text-decoration:none;font-size:var(--rsp-fs-100);line-height:2.15384615;min-height:30px;margin:0;padding:4px 8px;min-width:100px;text-align:center;cursor:pointer;font-weight:600;-webkit-appearance:none;border-radius:var(--rsp-border-radius-xs);white-space:nowrap;box-sizing:border-box;background-color:var(--rsp-yellow);color:var(--rsp-black);border-color:var(--rsp-yellow)}.rsssl-btn-vulnerable:hover{text-decoration:underline}.rsssl-btn-vulnerable.rsssl-critical{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-high{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-medium{border-color:var(--rsp-yellow);color:var(--rsp-black);background-color:var(--rsp-yellow)}

View File

@@ -0,0 +1,47 @@
/*
This was created for styling the plugin overview page for vulnerable plugins.
*/
@import "variables.scss";
.rsssl-btn-vulnerable {
display: inline-block;
text-decoration: none;
font-size: var(--rsp-fs-100);
line-height: 2.15384615;
min-height: 30px;
margin: 0;
padding: 4px 8px;
min-width: 100px;
text-align: center;
cursor: pointer;
font-weight: 600;
-webkit-appearance: none;
border-radius: var(--rsp-border-radius-xs);
white-space: nowrap;
box-sizing: border-box;
background-color: var(--rsp-yellow);
color: var(--rsp-black);
border-color: var(--rsp-yellow);
&:hover {
text-decoration: underline;
}
&.rsssl-critical {
background-color: var(--rsp-red);
color: var(--rsp-white);
border-color: var(--rsp-red);
}
&.rsssl-high {
background-color: var(--rsp-red);
color: var(--rsp-white);
border-color: var(--rsp-red);
}
&.rsssl-medium {
border-color: var(--rsp-yellow);
color: var(--rsp-black);
background-color: var(--rsp-yellow);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
:root{--rsp-spacing-xxs:5px;--rsp-spacing-xs:10px;--rsp-spacing-s:15px;--rsp-spacing-m:20px;--rsp-spacing-l:25px;--rsp-spacing-xl:30px;--rsp-grid-margin:var(--rsp-spacing-s);--rsp-grid-gap:var(--rsp-spacing-m);--rsp-border-radius:12px;--rsp-border-radius-s:8px;--rsp-border-radius-xs:3px;--rsp-border:1px solid var(--rsp-border-color);--rsp-box-shadow:rgba(0,0,0,0.1) 0 4px 6px -1px,rgba(0,0,0,0.06) 0 2px 4px -1px;--rsp-box-shadow-dark:rgba(0,0,0,0.2) 0 4px 6px -1px,rgba(0,0,0,0.12) 1px 0 4px 1px;--rsp-border-color:#dfdfdf;--rsp-black:#333;--rsp-white:#fff;--rsp-yellow:#fbc43e;--rsp-blue:#009fff;--rsp-dark-yellow:#e6a800;--rsp-dark-blue:#1e73be;--rsp-green:#2e8a37;--rsp-red:#d7263d;--rsp-dark-red:#9b0212;--rsp-pink:#e35899;--rsp-wp-blue:#007cba;--rsp-yellow-faded:#fdf4df;--rsp-blue-faded:#ecf8fe;--rsp-dark-blue-faded:#ebf2f9;--rsp-green-faded:#ecf4ed;--rsp-red-faded:#fbebed;--rsp-pink-faded:#fceff5;--rsp-wp-blue-faded:#c6e0ef;--rsp-background-block-color:var(--rsp-white);--rsp-background-color:#f0f0f1;--rsp-input-background-color:#fff;--rsp-input-text-color:var(--rsp-text-color);--rsp-input-border-color:var(--rsp-grey-400);--rsp-text-color:rgba(26,26,26,0.9);--rsp-text-color-invert:rgba(255,255,255,0.9);--rsp-text-color-white:rgba(255,255,255,0.9);--rsp-text-color-light:rgba(69,69,82,0.9);--rsp-text-color-hover:var(--rsp-green);--rsp-grey-100:#fafafa;--rsp-grey-200:#f7f7f7;--rsp-grey-300:#ededed;--rsp-grey-400:#c6c6c6;--rsp-grey-500:#737373;--rsp-grey-600:#696969;--rsp-color-success:var(--rsp-green);--rsp-color-error:var(--rsp-red);--rsp-color-warning:var(--rsp-yellow);--rsp-color-open:var(--rsp-yellow);--rsp-color-disabled:var(--rsp-grey-300);--rsp-fs-100:.6875rem;--rsp-fs-200:.75rem;--rsp-fs-300:.8125rem;--rsp-fs-400:.875rem;--rsp-fs-500:1rem;--rsp-fs-600:1.125rem;--rsp-fs-700:1.25rem;--rsp-fs-800:1.5rem;--rsp-fs-850:2.8rem;--rsp-fs-900:3.5rem}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}.rsssl-btn-vulnerable{display:inline-block;text-decoration:none;font-size:var(--rsp-fs-100);line-height:2.15384615;min-height:30px;margin:0;padding:4px 8px;min-width:100px;text-align:center;cursor:pointer;font-weight:600;-webkit-appearance:none;border-radius:var(--rsp-border-radius-xs);white-space:nowrap;box-sizing:border-box;background-color:var(--rsp-yellow);color:var(--rsp-black);border-color:var(--rsp-yellow)}.rsssl-btn-vulnerable:hover{text-decoration:underline}.rsssl-btn-vulnerable.rsssl-critical{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-high{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-medium{border-color:var(--rsp-yellow);color:var(--rsp-black);background-color:var(--rsp-yellow)}

View File

@@ -0,0 +1 @@
:root{--rsp-spacing-xxs:5px;--rsp-spacing-xs:10px;--rsp-spacing-s:15px;--rsp-spacing-m:20px;--rsp-spacing-l:25px;--rsp-spacing-xl:30px;--rsp-grid-margin:var(--rsp-spacing-s);--rsp-grid-gap:var(--rsp-spacing-m);--rsp-border-radius:12px;--rsp-border-radius-s:8px;--rsp-border-radius-xs:3px;--rsp-border:1px solid var(--rsp-border-color);--rsp-box-shadow:rgba(0,0,0,0.1) 0 4px 6px -1px,rgba(0,0,0,0.06) 0 2px 4px -1px;--rsp-box-shadow-dark:rgba(0,0,0,0.2) 0 4px 6px -1px,rgba(0,0,0,0.12) 1px 0 4px 1px;--rsp-border-color:#dfdfdf;--rsp-black:#333;--rsp-white:#fff;--rsp-yellow:#fbc43e;--rsp-blue:#009fff;--rsp-dark-yellow:#e6a800;--rsp-dark-blue:#1e73be;--rsp-green:#2e8a37;--rsp-red:#d7263d;--rsp-dark-red:#9b0212;--rsp-pink:#e35899;--rsp-wp-blue:#007cba;--rsp-yellow-faded:#fdf4df;--rsp-blue-faded:#ecf8fe;--rsp-dark-blue-faded:#ebf2f9;--rsp-green-faded:#ecf4ed;--rsp-red-faded:#fbebed;--rsp-pink-faded:#fceff5;--rsp-wp-blue-faded:#c6e0ef;--rsp-background-block-color:var(--rsp-white);--rsp-background-color:#f0f0f1;--rsp-input-background-color:#fff;--rsp-input-text-color:var(--rsp-text-color);--rsp-input-border-color:var(--rsp-grey-400);--rsp-text-color:rgba(26,26,26,0.9);--rsp-text-color-invert:rgba(255,255,255,0.9);--rsp-text-color-white:rgba(255,255,255,0.9);--rsp-text-color-light:rgba(69,69,82,0.9);--rsp-text-color-hover:var(--rsp-green);--rsp-grey-100:#fafafa;--rsp-grey-200:#f7f7f7;--rsp-grey-300:#ededed;--rsp-grey-400:#c6c6c6;--rsp-grey-500:#737373;--rsp-grey-600:#696969;--rsp-color-success:var(--rsp-green);--rsp-color-error:var(--rsp-red);--rsp-color-warning:var(--rsp-yellow);--rsp-color-open:var(--rsp-yellow);--rsp-color-disabled:var(--rsp-grey-300);--rsp-fs-100:.6875rem;--rsp-fs-200:.75rem;--rsp-fs-300:.8125rem;--rsp-fs-400:.875rem;--rsp-fs-500:1rem;--rsp-fs-600:1.125rem;--rsp-fs-700:1.25rem;--rsp-fs-800:1.5rem;--rsp-fs-850:2.8rem;--rsp-fs-900:3.5rem}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}.rsssl-btn-vulnerable{display:inline-block;text-decoration:none;font-size:var(--rsp-fs-100);line-height:2.15384615;min-height:30px;margin:0;padding:4px 8px;min-width:100px;text-align:center;cursor:pointer;font-weight:600;-webkit-appearance:none;border-radius:var(--rsp-border-radius-xs);white-space:nowrap;box-sizing:border-box;background-color:var(--rsp-yellow);color:var(--rsp-black);border-color:var(--rsp-yellow)}.rsssl-btn-vulnerable:hover{text-decoration:underline}.rsssl-btn-vulnerable.rsssl-critical{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-high{background-color:var(--rsp-red);color:var(--rsp-white);border-color:var(--rsp-red)}.rsssl-btn-vulnerable.rsssl-medium{border-color:var(--rsp-yellow);color:var(--rsp-black);background-color:var(--rsp-yellow)}

View File

@@ -0,0 +1,148 @@
// Break points
$rsp-break-xxs: 576px;
$rsp-break-xs: 768px;
$rsp-break-s: 1080px;
$rsp-break-m: 1280px;
$rsp-break-l: 1366px;
$rsp-break-xl: 1440px; // common 13 inch macbook pro width is 1425px
$rsp-break-xxl: 1599px;
:root {
// Margins, Paddings and Border Radius
--rsp-spacing-xxs: 5px;
--rsp-spacing-xs: 10px;
--rsp-spacing-s: 15px;
--rsp-spacing-m: 20px;
--rsp-spacing-l: 25px;
--rsp-spacing-xl: 30px;
// Grid settings
--rsp-grid-margin: var(--rsp-spacing-s);
--rsp-grid-gap: var(--rsp-spacing-m);
// Borders and stuff
--rsp-border-radius: 12px;
--rsp-border-radius-s: 8px;
--rsp-border-radius-xs: 3px;
--rsp-border: 1px solid var(--rsp-border-color);
--rsp-box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
--rsp-box-shadow-dark: rgba(0, 0, 0, 0.2) 0px 4px 6px -1px, rgba(0, 0, 0, 0.12) 1px 0px 4px 1px;
--rsp-border-color: #dfdfdf;
// RSP Brand Colors
--rsp-black: #333;
--rsp-white: #fff;
--rsp-yellow: #fbc43e;
--rsp-blue: #009fff;
--rsp-dark-yellow: #e6a800;
--rsp-dark-blue: #1E73BE;
--rsp-green: #2e8a37;
--rsp-red: #D7263D;
--rsp-dark-red: #9b0212;
--rsp-pink: #E35899;
--rsp-wp-blue: #007cba;
--rsp-yellow-faded: #fdf4df;
--rsp-blue-faded: #ecf8fe;
--rsp-dark-blue-faded: #ebf2f9;
--rsp-green-faded: #ecf4ed;
--rsp-red-faded: #fbebed;
--rsp-pink-faded: #fceff5;
--rsp-wp-blue-faded: #c6e0ef;
--rsp-background-block-color: var(--rsp-white);
--rsp-background-color: #f0f0f1; //#f0f0f1 is the default wordpress bg color
//Input colors
--rsp-input-background-color: #fff;
--rsp-input-text-color: var(--rsp-text-color);
--rsp-input-border-color: var(--rsp-grey-400);
--rsp-text-color: rgba(26, 26, 26, 0.9);
--rsp-text-color-invert: rgba(255, 255, 255, 0.9);
--rsp-text-color-white: rgba(255, 255, 255, 0.9);
--rsp-text-color-light: rgba(69, 69, 82, 0.9);
--rsp-text-color-hover: var(--rsp-green);
--rsp-grey-100: #fafafa;
--rsp-grey-200: #f7f7f7;
--rsp-grey-300: #ededed;
--rsp-grey-400: #c6c6c6;
--rsp-grey-500: #737373;
--rsp-grey-600: #696969;
// Notification colors
--rsp-color-success: var(--rsp-green);
--rsp-color-error: var(--rsp-red);
--rsp-color-warning: var(--rsp-yellow);
--rsp-color-open: var(--rsp-yellow);
--rsp-color-disabled: var(--rsp-grey-300);
// Font sizes
// If browser font-size is 16px:
--rsp-fs-100: 0.6875rem; // 11px
--rsp-fs-200: 0.75rem; // 12px
--rsp-fs-300: 0.8125rem; // 13px
--rsp-fs-400: 0.875rem; // 14px
--rsp-fs-500: 1rem; // 16px
--rsp-fs-600: 1.125rem; // 18px
--rsp-fs-700: 1.25rem; // 20px
--rsp-fs-800: 1.5rem; // 24px
--rsp-fs-850: 2.8rem; // 45px
--rsp-fs-900: 3.5rem; // 56px
}
@mixin rsssl-block {
background: var(--rsp-background-block-color);
box-shadow: var(--rsp-box-shadow);
border-radius: var(--rsp-border-radius);
}
@mixin rsssl-block-padding {
padding: var(--rsp-spacing-m) var(--rsp-spacing-l);
@media screen and (max-width: $rsp-break-m) {
padding: var(--rsp-spacing-xs) var(--rsp-spacing-s);
}
@media screen and (max-width: $rsp-break-s) {
padding: var(--rsp-spacing-xs) var(--rsp-spacing-s);
}
//@media screen and (max-width: $rsp-break-xs) {
// padding: var(--rsp-spacing-xs) var(--rsp-spacing-s);
//}
}
@mixin rsssl-block-block-padding {
padding-block: var(--rsp-spacing-m);
@media screen and (max-width: $rsp-break-m) {
padding-block: var(--rsp-spacing-xs);
}
@media screen and (max-width: $rsp-break-s) {
padding-block: var(--rsp-spacing-xxs);
}
}
@mixin rsssl-inline-block-padding {
padding-inline: var(--rsp-spacing-l);
@media screen and (max-width: $rsp-break-m) {
padding-inline: var(--rsp-spacing-m);
}
@media screen and (max-width: $rsp-break-s) {
padding-inline: var(--rsp-spacing-s);
}
}
@mixin rsssl-fade-in {
animation-name: fade-in;
animation-duration: 0.4s;
animation-timing-function: ease-in;
}
@keyframes fade-in{
0% { opacity: 0 }
100% { opacity: 1; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="uuid-08f50aea-a881-4760-b3e9-ea3b35fdcd17" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 425.3 521.17"><defs><style>.uuid-6af74af6-ef59-4374-b355-15aabae73c20{fill:#f9c23e;}.uuid-86115448-8ec8-4d68-95bb-6c993364e1fc,.uuid-10660db3-05b3-4992-88ee-574ec7dbb26e{fill:#eeeeef;}.uuid-bc936226-3aa0-45ec-ab25-2799b9313a06{fill:#646970;}.uuid-10660db3-05b3-4992-88ee-574ec7dbb26e,.uuid-8bc9deb7-f27b-4cc1-880f-badd82d2a5cb{stroke:#dcdcdc;stroke-miterlimit:10;stroke-width:9px;}.uuid-8bc9deb7-f27b-4cc1-880f-badd82d2a5cb{fill:#fff;}</style></defs><path class="uuid-8bc9deb7-f27b-4cc1-880f-badd82d2a5cb" d="m4.5,91.9v303.5c0,19.3,15.6,34.9,34.9,34.9h346.5c19.3,0,34.9-15.6,34.9-34.9V91.9H4.5Z"/><path class="uuid-10660db3-05b3-4992-88ee-574ec7dbb26e" d="m4.5,91.9v-52.5C4.5,20.1,20.1,4.5,39.4,4.5h346.5c19.3,0,34.9,15.6,34.9,34.9v52.5"/><g><circle class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" cx="61.15" cy="48.51" r="16.9"/><circle class="uuid-bc936226-3aa0-45ec-ab25-2799b9313a06" cx="116.35" cy="48.49" r="16.9"/><circle class="uuid-bc936226-3aa0-45ec-ab25-2799b9313a06" cx="171.65" cy="48.54" r="16.9"/></g><rect class="uuid-86115448-8ec8-4d68-95bb-6c993364e1fc" x="229.3" y="129.2" width="152.3" height="17.6"/><rect class="uuid-86115448-8ec8-4d68-95bb-6c993364e1fc" x="330.8" y="208.3" width="50.9" height="17.6"/><rect class="uuid-86115448-8ec8-4d68-95bb-6c993364e1fc" x="299.1" y="168.8" width="82.6" height="17.6"/><g><path class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" d="m91,194.9c-48.7,38.7-56.8,109.6-18.1,158.2,38.7,48.7,109.6,56.8,158.2,18.1,48.7-38.7,56.8-109.6,18.1-158.2-38.7-48.7-109.6-56.8-158.2-18.1Zm122.7,154.3c-36.5,29-89.7,23-118.7-13.6-29-36.5-23-89.7,13.6-118.7,36.5-29,89.7-23,118.7,13.6,29,36.5,23,89.7-13.6,118.7Z"/><rect class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" x="227.29" y="346.05" width="21" height="65.8" transform="translate(-184.21 230.41) rotate(-38.5)"/><rect class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" x="268.77" y="382.65" width="52.7" height="137" transform="translate(-216.69 281.79) rotate(-38.5)"/></g><g><g><path class="uuid-bc936226-3aa0-45ec-ab25-2799b9313a06" d="m184.9,284.7l-64.5,20.1c-2.6.8-5.2-1.1-5.2-3.9v-60c0-2.2,1.8-4,4-4h37.3c1.3,0,2.6.7,3.3,1.8l27.2,40c1.5,2.2.5,5.3-2.1,6.1v-.1Z"/><rect x="115.2" y="254" width="94.3" height="69.6" rx="6.4" ry="6.4"/></g><g><rect class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" x="157" y="298.1" width="11" height="10.4" rx="1.6" ry="1.6"/><path class="uuid-6af74af6-ef59-4374-b355-15aabae73c20" d="m167.6,291.6c0,.9-.8,1.6-1.6,1.6h-7.1c-.9,0-1.6-.7-1.6-1.6l-1-23.1c0-.9.7-1.7,1.6-1.7h9c.9,0,1.7.8,1.6,1.7l-1,23.1h.1Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
<?php
defined('ABSPATH') or die("you do not have access to this page!");
if ( ! class_exists( 'rsssl_cache' ) ) {
class rsssl_cache {
private static $_this;
function __construct() {
if ( isset( self::$_this ) )
wp_die( sprintf( __( '%s is a singleton class and you cannot create a second instance.','really-simple-ssl' ), get_class( $this ) ) );
self::$_this = $this;
}
static function this() {
return self::$_this;
}
/**
* Flushes the cache for popular caching plugins to prevent mixed content errors
* When .htaccess is changed, all traffic should flow over https, so clear cache when possible.
* supported: W3TC, WP fastest Cache, Zen Cache, wp_rocket
*
* @since 2.0
*
* @access public
*
*/
public function flush() {
if (!rsssl_user_can_manage()) return;
add_action( 'admin_head', array($this,'maybe_flush_w3tc_cache'));
add_action( 'admin_head', array($this,'maybe_flush_wp_optimize_cache'));
add_action( 'admin_head', array($this,'maybe_flush_litespeed_cache'));
add_action( 'admin_head', array($this,'maybe_flush_hummingbird_cache'));
add_action( 'admin_head', array($this,'maybe_flush_fastest_cache'));
add_action( 'admin_head', array($this,'maybe_flush_autoptimize_cache'));
add_action( 'admin_head', array($this,'maybe_flush_wp_rocket'));
add_action( 'admin_head', array($this,'maybe_flush_cache_enabler'));
add_action( 'admin_head', array($this,'maybe_flush_wp_super_cache'));
}
public function maybe_flush_w3tc_cache() {
if (!rsssl_user_can_manage()) return;
if ( function_exists('w3tc_flush_all') ) {
w3tc_flush_all();
}
}
public function maybe_flush_wp_optimize_cache() {
if (!rsssl_user_can_manage()) return;
if ( function_exists('wpo_cache_flush') ) {
wpo_cache_flush();
}
}
public function maybe_flush_litespeed_cache() {
if (!rsssl_user_can_manage()) return;
if ( class_exists('LiteSpeed') ) {
Litespeed\Purge::purge_all();
}
}
public function maybe_flush_hummingbird_cache() {
if (!rsssl_user_can_manage()) return;
if ( is_callable( array('Hummingbird\WP_Hummingbird', 'flush_cache') ) ) {
Hummingbird\WP_Hummingbird::flush_cache();
}
}
public function maybe_flush_fastest_cache() {
if (!rsssl_user_can_manage()) return;
if( class_exists('WpFastestCache') ) {
// Non-static cannot be called statically ::
(new WpFastestCache)->deleteCache();
}
}
public function maybe_flush_autoptimize_cache() {
if (!rsssl_user_can_manage()) return;
if ( class_exists('autoptimizeCache') ) {
autoptimizeCache::clearall();
}
}
public function maybe_flush_wp_rocket() {
if (!rsssl_user_can_manage()) return;
if ( function_exists('rocket_clean_domain') ) {
rocket_clean_domain();
}
}
public function maybe_flush_cache_enabler() {
if (!rsssl_user_can_manage()) return;
if ( class_exists('Cache_Enabler') ) {
Cache_Enabler::clear_complete_cache();
}
}
public function maybe_flush_wp_super_cache() {
if (!rsssl_user_can_manage()) return;
if ( function_exists( 'wp_cache_clear_cache' ) ) {
wp_cache_clear_cache();
}
}
}//class closure
}

View File

@@ -0,0 +1,282 @@
<?php defined('ABSPATH') or die();
if ( ! class_exists( 'rsssl_certificate' ) ) {
class rsssl_certificate
{
private static $_this;
function __construct()
{
if (isset(self::$_this))
wp_die(sprintf(__('%s is a singleton class and you cannot create a second instance.', 'really-simple-ssl'), get_class($this)));
self::$_this = $this;
}
static function this()
{
return self::$_this;
}
/**
*
* @since 3.0
*
* Check if the certificate is valid
*
* @return bool
*
*/
public function is_valid()
{
$domain = $this->get_domain();
if ( !$domain || !function_exists('stream_context_get_params') ) {
set_transient('rsssl_certinfo', 'no-response', DAY_IN_SECONDS);
} else {
$certinfo = $this->get_certinfo($domain);
if ( !$certinfo ) {
return false;
}
$domain_valid = $this->is_domain_valid($certinfo, $domain);
$date_valid = $this->is_date_valid($certinfo);
if ( $domain_valid && $date_valid ) {
return true;
}
}
return false;
}
/**
* get domain
* @return string
*/
public function get_domain(){
$domain = site_url();
//Parse to strip off any /subfolder/
$parse = parse_url($domain);
return isset($parse['host']) ? $parse['host'] : false;
}
/**
*
* Check common name(s) and alternative name(s) on certificate and match them to the site_url ($domain)
*
* @since 3.0
*
* @access public
*
* @return bool
*
*/
public function is_domain_valid($certinfo, $domain)
{
//first check standard situation
//Get both the common name(s) and the alternative names from the certificate
$certificate_common_names = isset($certinfo['subject']['CN']) ? $certinfo['subject']['CN'] : '';
$certificate_alternative_names = isset($certinfo['extensions']['subjectAltName']) ? $certinfo['extensions']['subjectAltName'] : '';
//Check if the domain is found in either the certificate common name(s) (CN) or alternative name(s) (AN)
$pos_cn = strpos($certificate_common_names, $domain);
$pos_an = strpos($certificate_alternative_names, $domain);
//If the domain is found, return true
if (($pos_cn !== false) || ($pos_an !== false)) {
return true;
}
//if nothing found, we check for wildcard
//strip of asterisk, and check if the wildcard domain is part of current domain
$cert_domains = array();
if ( $this->is_wildcard() ) {
$certificate_alternative_names = explode(', ',$certificate_alternative_names);
$cert_domains[] = trim(str_replace('*', '', $certificate_common_names));
foreach ($certificate_alternative_names as $subjectAltName) {
$cert_domains[] = trim(str_replace('*', '', $subjectAltName));
}
foreach ($cert_domains as $cert_domain){
//If the wildcard domain is found, return true
if ( (strpos($domain, $cert_domain ) !== false) ) {
return true;
}
}
}
return false;
}
/**
* Check if detection failed
* @return bool
*/
public function detection_failed(){
$certinfo = get_transient('rsssl_certinfo');
if ($certinfo && $certinfo === 'no-response' ) {
return true;
}
return false;
}
/**
*
* Check if the date is valid by looking at the validFrom and validTo times
*
* @since 3.0
*
* @access public
*
* @return bool
*
*/
public function is_date_valid($certinfo)
{
//Get the start date and end date from the certificate
$start_date = isset($certinfo['validFrom_time_t']) ? $certinfo['validFrom_time_t'] : false;
$end_date = isset($certinfo['validTo_time_t']) ? $certinfo['validTo_time_t'] : false;
$current_date = time();
//Check if the current date is between the start date and end date. If so, return true
if ($current_date > $start_date && ($current_date < $end_date)) {
return true;
}
return false;
}
/**
* Check if the certificate is valid, but about to expire.
* @return bool
*/
public function about_to_expire(){
//if not valid, it's already expired
if ( !$this->is_valid() ) {
return true;
}
//we have now renewed the cert info transient
$certinfo = get_transient('rsssl_certinfo');
$end_date = isset($certinfo['validTo_time_t']) ? $certinfo['validTo_time_t'] : false;
$expiry_days_time = strtotime('+'.rsssl_le_manual_generation_renewal_check.' days');
if ( $expiry_days_time < $end_date ) {
return false;
} else {
return true;
}
}
/**
*
* Check if the certificate is a wildcard certificate
* Function is used in class-multisite.php to determine whether to show a notice for multisite subfolder installations without a wildcard certificate
*
* @since 3.0
*
* @access public
*
* @return bool
*
*/
public function is_wildcard()
{
$domain = network_site_url();
$certinfo = $this->get_certinfo($domain);
//Get the certificate common name
$certificate_common_name = isset($certinfo['subject']['CN']) ? $certinfo['subject']['CN'] : false;
$subjectAltNames = isset($certinfo['extensions']['subjectAltName']) ? explode(', ',$certinfo['extensions']['subjectAltName']) : false;
//Check if the common name(s) contain an *
if (strpos($certificate_common_name, '*')) {
return true;
}
if (is_array($subjectAltNames)) {
foreach ($subjectAltNames as $subjectAltName) {
if ( strpos($subjectAltName, '*') !== false ) {
return true;
}
}
}
return false;
}
/**
*
* Get the certificate info
*
* @since 3.0
* @param string $url
* @return string|bool
* @access public
*
*/
public function get_certinfo( $url )
{
$certinfo = get_transient('rsssl_certinfo' );
//if the last check resulted in a "no response", we skip this check for a day.
if ($certinfo === 'no-response') {
return false;
}
if (!$certinfo || RSSSL()->admin->is_settings_page()) {
$url = 'https://'.str_replace(array('https://', 'http://'), '', $url);
$original_parse = parse_url($url, PHP_URL_HOST);
if ($original_parse) {
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));
if ( $get ) {
set_error_handler(array($this, 'custom_error_handling'));
$read = stream_socket_client("ssl://" . $original_parse . ":443", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $get);
restore_error_handler();
if ( !$read ){
$certinfo = 'no-response';
}
if ($errno == 0 && $read) {
$cert = stream_context_get_params($read);
if ( isset($cert['options']['ssl']['peer_certificate']) ) {
$certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
} else {
$certinfo = 'no-response';
}
}
}
}
set_transient('rsssl_certinfo', $certinfo, DAY_IN_SECONDS);
}
if ( $certinfo==='not-valid' ) return false;
if ( !empty($certinfo) ) {
return $certinfo;
}
return false;
}
/**
* Catch errors
*
* @since 3.0
*
* @access public
* @param $errno
* @param $errstr
* @param $errfile
* @param $errline
* @param array $errcontext
*
* @return bool
*/
public function custom_error_handling( $errno, $errstr, $errfile, $errline, $errcontext = array() ) {
return true;
}
//class closure
}
}

View File

@@ -0,0 +1,90 @@
<?php
defined('ABSPATH') or die("you do not have access to this page!");
if ( ! class_exists( 'rsssl_front_end' ) ) {
class rsssl_front_end
{
private static $_this;
public $wp_redirect;
public $ssl_enabled;
function __construct()
{
if (isset(self::$_this))
wp_die(sprintf('%s is a singleton class and you cannot create a second instance.', get_class($this)));
self::$_this = $this;
$this->ssl_enabled = rsssl_get_option('ssl_enabled');
$this->wp_redirect = rsssl_get_option('redirect', 'redirect') === 'wp_redirect';
add_action( 'rest_api_init', array($this, 'wp_rest_api_force_ssl'), ~PHP_INT_MAX);
}
static function this()
{
return self::$_this;
}
/**
* PHP redirect, when ssl is true.
*
* @since 2.2
*
* @access public
*
*/
public function force_ssl()
{
if ( $this->ssl_enabled && $this->wp_redirect ) {
add_action('wp', array($this, 'wp_redirect_to_ssl'), 40, 3);
}
}
/**
* Force SSL on wp rest api
*
* @since 2.5.14
*
* @access public
*
*/
public function wp_rest_api_force_ssl(): void {
//check for Command Line
if (php_sapi_name() === 'cli') return;
if (!array_key_exists('HTTP_HOST', $_SERVER)) return;
if ($this->ssl_enabled && !is_ssl() && !(defined("rsssl_no_rest_api_redirect") && rsssl_no_rest_api_redirect)) {
$redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
wp_redirect($redirect_url, 301);
exit;
}
}
/**
* Redirect using wp redirect
*
* @since 2.5.0
*
* @access public
*
*/
public function wp_redirect_to_ssl(): void {
if ( !array_key_exists('HTTP_HOST', $_SERVER) ) {
return;
}
if ( !is_ssl() && !(defined("rsssl_no_wp_redirect") && rsssl_no_wp_redirect) ) {
$redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$redirect_url = apply_filters("rsssl_wp_redirect_url", $redirect_url);
wp_redirect($redirect_url, 301);
exit;
}
}
}
}

View File

@@ -0,0 +1,175 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
if (!function_exists('is_plugin_active')) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
/**
* Install suggested plugins
*/
if ( !class_exists('rsssl_installer') ){
class rsssl_installer {
private $slug = '';
public function __construct($slug) {
if ( !current_user_can('install_plugins') ) return;
$this->slug = $slug;
}
/**
* Check if plugin is downloaded
* @return bool
*/
public function plugin_is_downloaded(){
return file_exists(trailingslashit (WP_PLUGIN_DIR).$this->get_activation_slug() );
}
/**
* Check if plugin is activated
* @return bool
*/
public function plugin_is_activated(){
return is_plugin_active($this->get_activation_slug());
}
/**
* Install plugin
* @param string $step
*
* @return void
*/
public function install($step){
if ( !current_user_can('install_plugins') ) return;
if ( $step === 'download' ) {
$this->download_plugin();
}
if ( $step === 'activate' ) {
$this->activate_plugin();
}
}
/**
* Get slug to activate plugin with
* @return string
*/
public function get_activation_slug(){
$slugs = [
'burst-statistics' => 'burst-statistics/burst.php',
'complianz-gdpr' => 'complianz-gdpr/complianz-gpdr.php',
'complianz-terms-conditions' => 'complianz-terms-conditions/complianz-terms-conditions.php',
];
return $slugs[$this->slug];
}
/**
* Cancel shepherd tour
* @return void
*/
public function cancel_tour(){
$prefixes = [
'burst-statistics' => 'burst',
'complianz-gdpr' => 'cmplz',
'complianz-terms-conditions' => 'cmplz_tc',
];
$prefix = $prefixes[$this->slug];
update_site_option( $prefix.'_tour_started', false );
update_site_option( $prefix.'_tour_shown_once', true );
delete_transient($prefix.'_redirect_to_settings');
}
/**
* Download the plugin
* @return bool
* @todo restore
*/
public function download_plugin() {
if (!current_user_can('install_plugins')) {
return false;
}
if (get_transient("rsssl_plugin_download_active") !== $this->slug) {
set_transient("rsssl_plugin_download_active", $this->slug, MINUTE_IN_SECONDS);
$info = $this->get_plugin_info();
$download_link = esc_url_raw($info->versions['trunk']);
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
if ( ! is_writable(WP_PLUGIN_DIR ) ) {
return false;
}
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Plugin_Upgrader($skin);
$result = $upgrader->install($download_link);
if (is_wp_error($result)) {
return false;
}
delete_transient("rsssl_plugin_download_active");
}
return true;
}
/**
* Activate the plugin
*
* @return bool
*/
public function activate_plugin() {
if (!current_user_can('install_plugins')) {
return false;
}
$slug = $this->get_activation_slug();
$plugin_file_path = trailingslashit(WP_PLUGIN_DIR) . $slug;
// Make sure the plugin file exists before trying to activate it
if (!file_exists($plugin_file_path)) {
return false;
}
// Use plugin_basename to generate the correct slug, considering the WP_PLUGIN_DIR
$plugin_slug = plugin_basename($plugin_file_path);
$networkwide = is_multisite() && rsssl_is_networkwide_active();
if (!defined('DOING_CRON')) {
define('DOING_CRON', true);
}
$result = activate_plugin($plugin_slug, '', $networkwide);
if (is_wp_error($result)) {
return false;
}
$this->cancel_tour();
return true;
}
/**
* Get plugin info
* @return array|WP_Error
*/
public function get_plugin_info()
{
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$plugin_info = get_transient('rsssl_'.$this->slug . '_plugin_info');
if ( empty($plugin_info) ) {
$plugin_info = plugins_api('plugin_information', array('slug' => $this->slug));
if ( !is_wp_error($plugin_info) ) {
set_transient('rsssl_'.$this->slug . '_plugin_info', $plugin_info, WEEK_IN_SECONDS);
}
}
return $plugin_info;
}
}
}

View File

@@ -0,0 +1,183 @@
<?php
defined('ABSPATH') or die("you do not have access to this page!");
if (!class_exists('rsssl_admin_mixed_content_fixer')) {
class rsssl_mixed_content_fixer
{
private static $_this;
public $http_urls = array();
public $mixed_content_fixer = false;
public $hide_wordpress_version = false;
function __construct()
{
if (isset(self::$_this)) wp_die();
self::$_this = $this;
$this->mixed_content_fixer = is_ssl() && rsssl_get_option('mixed_content_fixer', true );
$this->hide_wordpress_version = rsssl_get_option('hide_wordpress_version' );
if ( !is_admin() && ($this->mixed_content_fixer || $this->hide_wordpress_version )) {
$this->handle_output_buffer();
} else if ( is_admin() && is_ssl() && rsssl_get_option("admin_mixed_content_fixer") ) {
$this->mixed_content_fixer = true;
$this->handle_output_buffer();
}
}
static function this()
{
return self::$_this;
}
/**
*
* add action hooks at the start and at the end of the WP process.
*
* @since 2.3
*
* @access public
*
*/
public function handle_output_buffer()
{
/* Do not fix mixed content when call is coming from wp_api or from xmlrpc */
if (defined('JSON_REQUEST') && JSON_REQUEST) return;
if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) return;
$this->build_url_list();
if ( is_admin() ) {
add_action("admin_init", array($this, "start_buffer"), 100);
add_action("shutdown", array($this, "end_buffer"), 999);
} else {
if ( rsssl_get_option("switch_mixed_content_fixer_hook") || (defined('RSSSL_CONTENT_FIXER_ON_INIT') && RSSSL_CONTENT_FIXER_ON_INIT)) {
add_action("init", array($this, "start_buffer"));
} else {
add_action("template_redirect", array($this, "start_buffer"));
}
add_action("shutdown", array($this, "end_buffer"), 999);
}
}
/**
* Apply the mixed content fixer.
*
* @since 2.3
*
* @access public
*
*/
public function filter_buffer($buffer)
{
if ( $this->mixed_content_fixer ) {
$buffer = $this->replace_insecure_links($buffer);
}
return apply_filters("rsssl_fixer_output", $buffer );
}
/**
* Start buffering the output
*
* @since 2.0
*
* @access public
*
*/
public function start_buffer()
{
ob_start(array($this, "filter_buffer"));
}
/**
* Flush the output buffer
*
* @since 2.0
*
* @access public
*
*/
public function end_buffer()
{
if (ob_get_length()) ob_end_flush();
}
/**
* Creates an array of insecure links that should be https and an array of secure links to replace with
*
* @since 2.0
*
* @access public
*
*/
public function build_url_list()
{
$home = str_replace("https://", "http://", get_option('home') );
$root = str_replace("://www.", "://", $home);
$www = str_replace("://", "://www.", $root);
//for the escaped version, we only replace the home_url, not it's www or non www counterpart, as it is most likely not used
$escaped_home = str_replace("/", "\/", $home);
$this->http_urls = array(
$www,
$root,
$escaped_home,
"src='http://",
'src="http://',
);
}
/**
* Just before the page is sent to the visitor's browser, all homeurl links are replaced with https.
*
* @since 1.0
*
* @access public
*
*/
public function replace_insecure_links($str)
{
//skip if file is xml
if ( strpos( $str, "<?xml" ) === 0 ) {
return $str;
}
$search_array = apply_filters('rlrsssl_replace_url_args', $this->http_urls);
$ssl_array = str_replace(array("http://", "http:\/\/"), array("https://", "https:\/\/"), $search_array);
$str = str_replace($search_array, $ssl_array, $str);
//replace all http links except hyperlinks
//all tags with src attr are already fixed by str_replace
$pattern = array(
'/url\([\'"]?\K(http:\/\/)(?=[^)]+)/i',
'/<link [^>]*?href=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
'/<meta property="og:image" [^>]*?content=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
'/<form [^>]*?action=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
);
$str = preg_replace($pattern, 'https://', $str);
/* handle multiple images in srcset */
$str = preg_replace_callback('/<img[^\>]*[^\>\S]+srcset=[\'"]\K((?:[^"\'\s,]+\s*(?:\s+\d+[wx])(?:,\s*)?)+)["\']/', array($this, 'replace_src_set'), $str);
return str_replace("<body", '<body data-rsssl=1', $str);
}
/**
* Helper function
*
* */
public function replace_src_set($matches) {
return str_replace("http://", "https://", $matches[0]);
}
}
}

View File

@@ -0,0 +1,656 @@
<?php defined('ABSPATH') or die();
if (!class_exists('rsssl_multisite')) {
class rsssl_multisite
{
private static $_this;
function __construct()
{
if (isset(self::$_this))
wp_die();
self::$_this = $this;
register_activation_hook( __DIR__ . "/" . rsssl_plugin, array($this, 'activate'));
add_action('network_admin_menu', array($this, 'add_plus_ones') );
/*filters to make sure WordPress returns the correct protocol */
add_filter("admin_url", array($this, "check_admin_protocol"), 20, 3);
add_filter('home_url', array($this, 'check_site_protocol'), 20, 4);
add_filter('site_url', array($this, 'check_site_protocol'), 20, 4);
add_action('network_admin_menu', array(&$this, 'add_multisite_menu'));
add_action('plugins_loaded', array($this, 'maybe_redirect_old_settings_url'), 10);
if ( is_network_admin() ) {
add_action('network_admin_notices', array($this, 'show_notices'), 10);
}
$plugin = rsssl_plugin;
add_filter( "network_admin_plugin_action_links_$plugin", array($this, 'plugin_settings_link') );
//If WP version is 5.1 or higher, use wp_insert_site hook for multisite SSL activation in new blogs
if( version_compare(get_bloginfo('version'),'5.1', '>=') ) {
add_action('wp_initialize_site', array($this, 'maybe_activate_ssl_in_new_blog'), 20, 1);
} else {
add_action('wpmu_new_blog', array($this, 'maybe_activate_ssl_in_new_blog_deprecated'), 10, 6);
}
add_filter('rsssl_notices', array($this, 'add_multisite_notices'));
}
static function this()
{
return self::$_this;
}
/**
* Redirect to the new settings page
*
* @return void
*/
public function maybe_redirect_old_settings_url(){
if ( !rsssl_user_can_manage() || !is_network_admin() ) {
return;
}
if ( isset($_GET['page']) && $_GET['page'] === 'rlrsssl_really_simple_ssl' ){
wp_redirect(add_query_arg(['page' => 'really-simple-security'], network_admin_url('settings.php') ) );
exit;
}
}
/**
*
* @since 3.1.6
*
* Add an update count to the WordPress admin Settings menu item
* Doesn't work when the Admin Menu Editor plugin is active
*
*/
public function add_plus_ones()
{
if (!rsssl_user_can_manage()) {
return;
}
$count = RSSSL()->admin->count_plusones();
if ( $count > 0 ) {
global $menu;
foreach( $menu as $index => $menu_item ){
if (!isset($menu_item[2]) || !isset($menu_item[0])) continue;
if ( $menu_item[2]==='settings.php' ){
$pattern = '/<span.*>([1-9])<\/span><\/span>/i';
if (preg_match($pattern, $menu_item[0], $matches)){
if (isset($matches[1])) $count = (int) $count + (int) $matches[1];
}
$menu[$index][0] = __('Settings') . "<span class='update-plugins rsssl-update-count'><span class='update-count'>$count</span></span>";
}
}
}
}
/**
* Add notices to the dashboard
* @param array $notices
*
* @return array
*/
public function add_multisite_notices( array $notices): array {
$unset_array = array(
'mixed_content_fixer_detected',
'elementor',
'divi',
);
foreach ( $unset_array as $unset_item ) {
unset( $notices[$unset_item] );
}
$notices['ssl_enabled'] = array(
'callback' => 'rsssl_ssl_enabled',
'score' => 30,
'output' => array(
'true' => array(
'msg' =>__('SSL is enabled networkwide.', 'really-simple-ssl'),
'icon' => 'success'
),
'false' => array(
'msg' => __('SSL is not enabled on your network', 'really-simple-ssl'),
'icon' => 'open',
'plusone' => true,
),
),
);
$notices['multisite_server_variable_warning'] = array(
'condition' => array('rsssl_ssl_enabled'),
'callback' => 'RSSSL()->multisite->multisite_server_variable_warning',
'score' => 30,
'output' => array(
'no-server-variable' => array(
'msg' => __('You run a Multisite installation with subfolders, which prevents this plugin from fixing your missing server variable in the wp-config.php.', 'really-simple-ssl') . " "
.__('Because the $_SERVER["HTTPS"] variable is not set, your website may experience redirect loops.', 'really-simple-ssl') . " "
.__('Activate networkwide to fix this.', 'really-simple-ssl'),
'icon' => 'warning',
'plusone' => true,
),
),
);
$notices['activation_not_completed'] = array(
'callback' => 'RSSSL()->multisite->ssl_activation_started_but_not_completed',
'score' => 30,
'output' => array(
'true' => array(
'title' => __("SSL activation in progress", "really-simple-ssl"),
'msg' => __('A networkwide SSL activation process has been started, but has not been completed. Please go to the SSL settings page to complete the process.', 'really-simple-ssl').'&nbsp;'.
'<a href="'.add_query_arg(['page'=>'really-simple-security'], network_admin_url('settings.php') ).'">'.__('View settings page','really-simple-ssl').'</a>',
'icon' => 'warning',
'plusone' => true,
'admin_notice' => true,
),
),
);
$notices['subdomains_no_wildcard'] = array(
'condition' => array('rsssl_ssl_enabled'),
'callback' => 'RSSSL()->multisite->subdomains_no_wildcard',
'score' => 30,
'output' => array(
'subdomains-no-wildcard' => array(
'msg' => __("You run a Multisite installation with subdomains, but your site doesn't have a wildcard certificate.", 'really-simple-ssl') . " "
. __("This leads to issues when activating SSL networkwide since subdomains will be forced over SSL as well while they don't have a valid certificate.", 'really-simple-ssl') . " "
. __("Activate SSL per site or install a wildcard certificate to fix this.", 'really-simple-ssl'),
'icon' => 'warning',
'dismissible' => true,
'plusone' => true,
),
),
);
return $notices;
}
/**
* Check if site has a server var issue.
* @return string
*/
public function multisite_server_variable_warning(){
if (!function_exists('is_plugin_active_for_network'))
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( is_multisite() && !is_plugin_active_for_network(rsssl_plugin) && $this->is_multisite_subfolder_install() ) {
//with no server variables, the website could get into a redirect loop.
if (RSSSL()->admin->no_server_variable) {
return 'no-server-variable';
}
}
return 'success';
}
/**
* Check if we have a subdomains setup, but no wildcard
* @return string
*/
public function subdomains_no_wildcard(){
if ( get_site_option('rsssl_network_activation_status' !== 'completed') && !$this->is_multisite_subfolder_install() && !RSSSL()->certificate->is_wildcard() ) {
return 'subdomains-no-wildcard';
}
return 'success';
}
/**
* Add settings link on plugins overview page
*
* @param array $links
*
* @return array
* @since 2.0
* @access public
*/
public function plugin_settings_link(array $links): array {
if ( !rsssl_user_can_manage() ) {
return $links;
}
$url = add_query_arg(array('page' => 'really-simple-security'), network_admin_url('settings.php') );
$settings_link = '<a href="' . $url . '">' . __("Settings", "really-simple-ssl") . '</a>';
array_unshift($links, $settings_link);
$support = apply_filters('rsssl_support_link', '<a target="_blank" href="https://wordpress.org/support/plugin/really-simple-ssl/">' . __('Support', 'really-simple-ssl') . '</a>');
array_unshift($links, $support);
if ( ! defined( 'rsssl_pro_version' ) ) {
$upgrade_link = '<a style="color:#2271b1;font-weight:bold" target="_blank" href="https://really-simple-ssl.com/pro/?mtm_campaign=settings&mtm_kwd=multisite&mtm_source=free&mtm_content=upgrade">' . __( 'Improve security - Upgrade', 'really-simple-ssl' ) . '</a>';
array_unshift( $links, $upgrade_link );
}
return $links;
}
/**
* When a new site is added, maybe activate SSL as well.
*
* @param int $blog_id
* @param bool $user_id
* @param bool $domain
* @param bool $path
* @param bool $site_id
* @param bool $meta
*/
public function maybe_activate_ssl_in_new_blog_deprecated( int $blog_id, $user_id=false, $domain=false, $path=false, $site_id=false, $meta=false)
{
if ( get_site_option('rsssl_network_activation_status' === 'completed') ) {
$site = get_blog_details($blog_id);
switch_to_blog($site->blog_id);
RSSSL()->admin->activate_ssl(false);
restore_current_blog();
}
}
/**
* Activate SSl in new block
* @since 3.1.6
* @param $site
* @return void
*/
public function maybe_activate_ssl_in_new_blog($site)
{
if ( get_site_option('rsssl_network_activation_status' === 'completed') ) {
switch_to_blog($site->blog_id);
RSSSL()->admin->activate_ssl(false);
restore_current_blog();
}
}
/**
Add network menu for SSL
Only when plugin is network activated.
*/
public function add_multisite_menu()
{
if ( !is_multisite() || !rsssl_is_networkwide_active() ) {
return;
}
if ( !rsssl_user_can_manage() ) {
return;
}
$count = RSSSL()->admin->count_plusones();
$update_count = $count > 0 ? "<span class='update-plugins rsssl-update-count'><span class='update-count'>$count</span></span>" : "";
$page_hook_suffix = add_submenu_page(
'settings.php',
__("SSL & Security","really-simple-ssl"),
__("SSL & Security","really-simple-ssl").' '.$update_count,
'manage_security',
"really-simple-security",
'rsssl_settings_page'
);
add_action( "admin_print_scripts-{$page_hook_suffix}", 'rsssl_plugin_admin_scripts' );
}
/**
* Check if an SSL process is active
* @return bool
*/
public function ssl_process_active(){
if ( get_site_option('rsssl_ssl_activation_active') ){
return true;
}
return false;
}
/**
* Run SSL upgrade process
*
* @return void
*/
public function run_ssl_process(){
if ( get_site_option('rsssl_ssl_activation_active') ){
$this->activate_ssl_networkwide();
}
update_site_option('rsssl_run', false);
}
/**
* @param WP_REST_Request $request
*
* @return array
*/
public function process_ssl_activation_step(){
if ( !$this->ssl_process_active() ) {
$this->start_ssl_activation();
}
$this->run_ssl_process();
$progress = $this->get_process_completed_percentage();
return [
'progress' => $progress,
'success' => true
];
}
/**
* Get SSL process completed percentage
* @return int
*/
public function get_process_completed_percentage(){
if ( get_site_option('rsssl_network_activation_status') === 'completed' ) {
return 100;
}
$complete_count = get_site_option('rsssl_siteprocessing_progress');
$blog_count = $this->get_total_blog_count();
$blog_count = $blog_count !== 0 ? $blog_count : 1; //prevent division by zero
$percentage = round(( $complete_count/$blog_count )*100,0);
if ( $percentage > 99 ) {
$percentage = 100;
}
return (int) $percentage;
}
/**
* Check if website has started activation, but didn't completed
* @return bool
*/
public function ssl_activation_started_but_not_completed(){
if ( !get_option('rsssl_network_activation_status') ) {
return false;
}
return get_option('rsssl_network_activation_status')!=='completed';
}
/**
* Start SSL activation
*
* @return void
*/
public function start_ssl_activation(){
if (!rsssl_user_can_manage()) {
return;
}
update_site_option('rsssl_siteprocessing_progress', 0);
update_site_option('rsssl_ssl_activation_active', true);
}
/**
* End SSL activation
*
* @return void
*/
public function end_ssl_activation(){
if (!rsssl_user_can_manage()) {
return;
}
update_site_option('rsssl_ssl_activation_active', false);
}
/**
* Activate SSL network wide
*/
public function activate_ssl_networkwide()
{
if (!rsssl_user_can_manage()) {
return;
}
//run chunked
$nr_of_sites = 200;
$current_offset = get_site_option('rsssl_siteprocessing_progress');
//set batch of sites
$args = array(
'number' => $nr_of_sites,
'offset' => $current_offset,
'meta_query' => [
'relation' => 'or',
[
'key' => 'rsssl_ssl_activated',
'compare' => 'NOT EXISTS'
],
[
'key' => 'rsssl_ssl_activated',
'value' => false,
'compare' => '=',
],
]
);
$sites = get_sites($args);
//if no sites are found, we assume we're done.
if ( count($sites)==0 ) {
$this->end_ssl_activation();
update_site_option('rsssl_network_activation_status', 'completed');
} else {
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
update_site_meta($site->blog_id, 'rsssl_ssl_activated', true );
RSSSL()->admin->activate_ssl(false);
restore_current_blog(); //switches back to previous blog, not current, so we have to do it each loop
update_site_option('rsssl_siteprocessing_progress', $current_offset+$nr_of_sites);
}
}
}
/**
* Deactivate SSL on all subsites
*
* @return void
*/
public function deactivate()
{
if (!rsssl_user_can_manage()) {
return;
}
$ssl_was_enabled = rsssl_get_option('ssl_enabled');
delete_site_option('rsssl_network_activation_status');
update_option('ssl_enabled', false);
//main site first
$site_id = get_main_site_id();
switch_to_blog($site_id);
RSSSL()->admin->deactivate_site($ssl_was_enabled);
restore_current_blog();
//because the deactivation should be a one click procedure, chunking this would cause difficulties
$args = array(
'number' => $this->get_total_blog_count(),
'offset' => 0,
);
$sites = get_sites($args);
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
update_site_meta($site->blog_id, 'rsssl_ssl_activated', false );
//we already did the main site
if ( !is_main_site() ) {
RSSSL()->admin->deactivate_site($ssl_was_enabled);
}
restore_current_blog();
}
}
/**
* filters the get_admin_url function to correct the false https urls wordpress returns for non SSL websites.
*
* @since 2.3.10
*
*/
public function check_admin_protocol($url, $path, $blog_id)
{
if ( !$blog_id ) $blog_id = get_current_blog_id();
//if the force_ssl_admin is defined, the admin_url should not be forced back to http: all admin panels should be https.
if (defined('FORCE_SSL_ADMIN')) return $url;
//do not force to http if the request is made for an url of the current blog.
//if a site is loaded over https, it should return https links, unless the url is requested for another blog.
//In that case, we only return a https link if the site_url is https, and http otherwise.
if (get_current_blog_id() == $blog_id) return $url;
//now check if the blog is http or https, and change the url accordingly
if (!function_exists('is_plugin_active_for_network'))
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( !is_plugin_active_for_network(rsssl_plugin) ) {
$home_url = get_blog_option($blog_id, 'home');
if (strpos($home_url, "https://") === false) {
$url = str_replace("https://", "http://", $url);
}
}
return $url;
}
/**
* filters the home_url and/or site_url function to correct the false https urls wordpress returns for non SSL websites.
*
* @since 2.3.17
*
*/
public function check_site_protocol($url, $path, $orig_scheme, $blog_id)
{
if ( !$blog_id ) {
$blog_id = get_current_blog_id();
}
if (get_current_blog_id() == $blog_id) return $url;
if (!function_exists('is_plugin_active_for_network'))
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
if ( !is_plugin_active_for_network(rsssl_plugin) ) {
$home_url = get_blog_option($blog_id, 'home');
if (strpos($home_url, "https://") === false) {
$url = str_replace("https://", "http://", $url);
}
}
return $url;
}
/**
* Checks if we are on a subfolder install. (domain.com/site1 )
*
* @since 2.2
*
* @access public
*
**/
public function is_multisite_subfolder_install()
{
if ( !is_multisite() ) {
return false;
}
//we check this manually, as the SUBDOMAIN_INSTALL constant of wordpress might return false for domain mapping configs
$is_subfolder = false;
$args = array(
'number' => 5,
'offset' => 0,
);
$sites = get_sites($args);
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
if ($this->is_subfolder(home_url())) {
$is_subfolder = true;
}
restore_current_blog(); //switches back to previous blog, not current, so we have to do it each loop
if ($is_subfolder) return true;
}
return false;
}
/**
* Test if a domain has a subfolder structure
*
* @since 2.2
*
* @param string $domain
*
* @access private
*
* @return bool
*/
public function is_subfolder($domain)
{
//remove slashes of the http(s)
$domain = preg_replace("/(http:\/\/|https:\/\/)/", "", $domain);
if ( strpos($domain, "/") !== FALSE ) {
return true;
}
return false;
}
/**
* Show notices
*
* @since 2.0
*
* @access public
*
*/
public function show_notices()
{
if ( !rsssl_user_can_manage() ) {
return;
}
//prevent showing the review on edit screen, as gutenberg removes the class which makes it editable.
$screen = get_current_screen();
if ( $screen && $screen->base === 'post' ) return;
if ( !$this->is_settings_page() ) {
$notices = RSSSL()->admin->get_notices_list( array('admin_notices'=>true) );
foreach ( $notices as $id => $notice ){
$notice = $notice['output'];
$class = ( $notice['status'] !== 'completed' ) ? 'error' : 'updated';
$more_info = $notice['url'] ?? false;
$dismiss_id = isset($notice['dismissible']) && $notice['dismissible'] ? $id : false;
echo RSSSL()->admin->notice_html( $class.' '.$id, $notice['msg'], $more_info, $dismiss_id);
}
}
}
/**
* Check if we are on the settings page
* @return bool
*/
public function is_settings_page()
{
if (!rsssl_user_can_manage()) {
return false;
}
return (isset($_GET['page']) && $_GET['page'] === 'really-simple-security');
}
/**
* Get blog count for all networks
*
* @return int
*/
public function get_total_blog_count()
{
//Get the total blog count from all multisite networks
$networks = get_networks();
$total_blog_count = 0;
foreach($networks as $network){
$network_id = ($network->__get('id'));
$blog_count = get_blog_count($network_id);
$total_blog_count += $blog_count;
}
return $total_blog_count;
}
} //class closure
}

View File

@@ -0,0 +1,77 @@
<?php
defined( 'ABSPATH' ) or die( "you do not have access to this page!" );
if ( ! class_exists( 'rsssl_server' ) ) {
class rsssl_server {
private static $_this;
function __construct() {
if ( isset( self::$_this ) ) {
wp_die( sprintf( '%s is a singleton class and you cannot create a second instance.', get_class( $this ) ) );
}
self::$_this = $this;
}
static function this() {
return self::$_this;
}
/**
* @Since 2.5.1
* Checks if the server uses .htaccess
* @return bool
*/
public function uses_htaccess() {
// No .htaccess on WP Engine
if ( function_exists( 'is_wpe' ) && is_wpe() ) {
return false;
}
if ( $this->get_server() === "apache" || $this->get_server() === "litespeed" ) {
return true;
}
return false;
}
/**
* Returns the server type of the plugin user.
*
* @return string|bool server type the user is using of false if undetectable.
*/
public function get_server() {
//Allows to override server authentication for testing or other reasons.
if ( defined( 'RSSSL_SERVER_OVERRIDE' ) ) {
return RSSSL_SERVER_OVERRIDE;
}
$server_raw = strtolower( htmlspecialchars( $_SERVER['SERVER_SOFTWARE'] ) );
//figure out what server they're using
if ( strpos( $server_raw, 'apache' ) !== false ) {
return 'apache';
} elseif ( strpos( $server_raw, 'nginx' ) !== false ) {
return 'nginx';
} elseif ( strpos( $server_raw, 'litespeed' ) !== false ) {
return 'litespeed';
} else { //unsupported server
return false;
}
}
/**
* Check if the apache version is at least 2.4
* @return bool
*/
public function apache_version_min_24(){
$version = $_SERVER['SERVER_SOFTWARE'] ?? false;
//check if version is higher then 2.4.
if ( preg_match('/Apache\/(2\.[4-9])/', $version, $matches) ){
return true;
}
return false;
}
} //class closure
}

View File

@@ -0,0 +1,236 @@
<?php defined('ABSPATH') or die();
if ( !class_exists("rsssl_site_health") ) {
class rsssl_site_health {
private static $_this;
function __construct() {
if ( isset( self::$_this ) ) {
wp_die( sprintf( __( '%s is a singleton class and you cannot create a second instance.', 'really-simple-ssl' ), get_class( $this ) ) );
}
add_filter( 'site_status_tests', array($this, 'health_check' ), 1, 10 );
self::$_this = $this;
}
static function this() {
return self::$_this;
}
/**
* Add SSL dedicated health check
* @param array $tests
*
* @return array
*/
public function health_check( $tests ) {
unset($tests['async']['https_status']);
if ( !rsssl_get_option('dismiss_all_notices') ) {
$tests['direct']['rsssl_ssl_health'] = array(
'label' => __( 'SSL Status Test' , 'really-simple-ssl'),
'test' => array($this, "ssl_tests"),
);
$tests['direct']['headers_test'] = array(
'label' => __( 'Security Headers Test' , 'really-simple-ssl' ),
'test' => array($this, "headers_test"),
);
unset( $tests['direct']['debug_enabled'] );
if ( rsssl_is_debugging_enabled() && rsssl_debug_log_value_is_default() ) {
$tests['direct']['rsssl_debug_log'] = array(
'test' => array( $this, "site_health_debug_log_test" ),
);
}
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) {
$tests['direct']['rsssl_debug_display'] = array(
'test' => array( $this, "site_health_debug_display_test" ),
);
}
if ( rsssl_get_option( 'enable_vulnerability_scanner' ) ) {
$vulnerabilities = new rsssl_vulnerabilities();
$tests['direct']["rsssl_vulnerabilities"] = array(
'test' => [ $vulnerabilities, "get_site_health_notice" ],
);
}
}
return $tests;
}
/**
* Generate the WP_DEBUG notice
*
*/
public function site_health_debug_log_test() {
$result = array(
'label' => __( 'Your site is set to log errors to a potentially public file' ),
'status' => 'critical',
'badge' => array(
'label' => __( 'Security' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'The value, WP_DEBUG_LOG, has been added to this websites configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ,'really-simple-ssl' )
),
'actions' => sprintf(
'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
/* translators: Documentation explaining debugging in WordPress. */
esc_url( __( add_query_arg(array('page'=>'really-simple-security#settings/hardening'), rsssl_admin_url() ) ) ),
__( 'Remove from public location with Really Simple SSL', 'really-simple-ssl' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )
),
'test' => 'rsssl_debug_log',
);
return $result;
}
/**
* Explain users about risks of debug display
*
*/
public function site_health_debug_display_test() {
$result = array(
'label' => __( 'Your site is set to display errors on your website', 'really-simple-ssl' ),
'status' => 'critical',
'badge' => array(
'label' => __( 'Security' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'The value, WP_DEBUG_DISPLAY, has either been enabled by WP_DEBUG or added to your configuration file. This will make errors display on the front end of your site.' ,'really-simple-ssl' )
),
'actions' => sprintf(
'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
/* translators: Documentation explaining debugging in WordPress. */
esc_url( 'https://really-simple-ssl.com/security/debug-display-enabled' ),
__( 'Read more about security concerns with debug display enabled', 'really-simple-ssl' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )
),
'test' => 'rsssl_debug_display',
);
return $result;
}
/**
* Test to check if the recommended security headers are present
* @return array
*/
public function headers_test() {
$result = array(
'label' => __( 'Recommended security headers installed', 'really-simple-ssl' ),
'status' => 'good',
'badge' => array(
'label' => __('Security'),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'The recommended security headers are detected on your site.', 'really-simple-ssl' )
),
'actions' => '',
'test' => 'headers_test',
);
//returns empty for sites without .htaccess, or if all headers are already in use
$recommended_headers = RSSSL()->admin->get_recommended_security_headers();
if (!empty($recommended_headers)) {
$style = '<style>.rsssl-sec-headers-list li {list-style-type:disc;margin-left:20px;}</style>';
$list = '<ul class="rsssl-sec-headers-list"><li>'.implode('</li><li>', $recommended_headers ).'</li></ul>';
$result['status'] = 'recommended';
$result['label'] = __( 'Not all recommended security headers are installed' , 'really-simple-ssl' );
$result['description'] = sprintf( '<p>%s</p>', __( 'Your website does not send all recommended security headers.', 'really-simple-ssl' ).$style.$list);
$result['actions'] = sprintf(
'<p><a href="%s" target="_blank">%s</a></p>',
'https://really-simple-ssl.com/site-health-recommended-security-headers/',
__( 'Learn more about security headers', 'really-simple-ssl' )
);
}
return $result;
}
/**
* Some basic SSL health checks
* @return array
*/
public function ssl_tests() {
$url = add_query_arg(array('page' => 'really-simple-security'), rsssl_admin_url() );
$result = array(
'label' => __( '301 SSL redirect enabled', 'really-simple-ssl' ),
'status' => 'good',
'badge' => array(
'label' => __('Security'),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'You have set a 301 redirect to SSL. This is important for SEO purposes', 'really-simple-ssl' )
),
'actions' => '',
'test' => 'rsssl_ssl_health',
);
if ( !rsssl_get_option('ssl_enabled') ) {
if ( rsssl_get_option('site_has_ssl') ) {
$result['status'] = 'critical';
$result['label'] = __( 'SSL is not enabled.', 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__( 'Really Simple SSL detected an SSL certificate, but has not been configured to enforce SSL.',
'really-simple-ssl' )
);
$result['actions'] .= sprintf(
'<p><a href="%s">%s</a></p>',
$url ,
__( 'Activate SSL', 'really-simple-ssl' )
);
} else {
$result['status'] = 'critical';
$result['label'] = __( 'No SSL detected.' , 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__( 'Really Simple SSL is installed, but no valid SSL certificate is detected.', 'really-simple-ssl' )
);
}
} else {
if ( !RSSSL()->admin->has_301_redirect() ) {
$result['status'] = 'recommended';
$result['label'] = __( 'No 301 redirect to SSL enabled.' , 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__( 'To ensure all traffic passes through SSL, please enable a 301 redirect.', 'really-simple-ssl' )
);
$result['actions'] .= sprintf(
'<p><a href="%s">%s</a></p>',
$url,
__( 'Enable 301 redirect', 'really-simple-ssl' )
);
} else if ( RSSSL()->server->uses_htaccess() && rsssl_get_option('redirect')!=='htaccess') {
$result['status'] = 'recommended';
$result['label'] = __( '301 .htaccess redirect is not enabled.' , 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__( 'The 301 .htaccess redirect is the fastest and most reliable redirect option.', 'really-simple-ssl' )
);
$result['actions'] .= sprintf(
'<p><a href="%s">%s</a></p>',
$url,
__( 'Enable 301 .htaccess redirect', 'really-simple-ssl' )
);
}
}
return $result;
}
}
}

View File

@@ -0,0 +1,84 @@
<?php
defined('ABSPATH') or die();
/**
* Usage
* php wp rsssl activate_ssl
* php wp rsssl deactivate_ssl
* php wp rsssl update_option --site_has_ssl=true
* php wp rsssl update_option --site_has_ssl=true --x_xss_protection=one
* or: php wp-cli.phar rsssl update_option --x_xss_protection=one
*/
class rsssl_wp_cli
{
public function __construct()
{
}
public function wp_cli_active() {
return defined( 'WP_CLI' ) && WP_CLI;
}
/**
* Activate SSL through CLI
*
* @return void
* @throws \WP_CLI\ExitException
*/
public function activate_ssl()
{
if ( !$this->wp_cli_active() ) {
return;
}
update_option("rsssl_onboarding_dismissed", true, false);
update_option('rsssl_6_upgrade_completed', true, false);
$success = RSSSL()->admin->activate_ssl(false);
if ($success) {
WP_CLI::success( 'SSL activated successfully' );
} else {
WP_CLI::error( 'SSL activation failed' );
}
}
/**
* Deactivate SSL through wp cli
*
* @return void
*/
public function deactivate_ssl()
{
if (!$this->wp_cli_active() ) {
return;
}
RSSSL()->admin->deactivate();
WP_CLI::success( 'SSL deactivated' );
}
/**
* @param $name
* @param $value
*
* @return void
* @throws \WP_CLI\ExitException
*/
public function update_option($args, $assoc_args)
{
if (!$this->wp_cli_active() ) {
return;
}
if ( empty($assoc_args) ) {
WP_CLI::error( 'No options passed' );
}
foreach ($assoc_args as $name => $value ) {
rsssl_update_option(sanitize_title($name), $value);
WP_CLI::success( "Option $name updated" );
}
}
}
WP_CLI::add_command( 'rsssl', 'rsssl_wp_cli' );

View File

@@ -0,0 +1,58 @@
<?php
defined('ABSPATH') or die();
/**
* File to prevent fatal errors when used with older pro versions
* @deprecated
*/
if ( is_admin() && rsssl_user_can_manage() ) {
class really_simple_ssl_legacy{
public $site_has_ssl;
public $ssl_enabled;
public function generate_enable_link(){}
public function find_wp_config_path(){return '-';}
public function contains_hsts(){}
public function get_recommended_security_headers(){return [];}
public function notice_html(){}
}
class rsssl_help_legacy {
public function get_help_tip(){}
}
class rsssl_mixed_content_fixer_legacy {
public function fix_mixed_content(){}
}
class rsssl_multisite_legacy {
public $ssl_enabled_networkwide;
public $mixed_content_admin;
public $cert_expiration_warning;
public $selected_networkwide_or_per_site;
public function plugin_network_wide_active(){
return false;
}
}
add_action('plugins_loaded', 'rsssl_compatibility_mode', 9);
function rsssl_compatibility_mode() {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
$plugin_data = false;
$ms_file = WP_CONTENT_DIR . '/plugins/really-simple-ssl-pro-multisite/really-simple-ssl-pro-multisite.php';
$pro_file = WP_CONTENT_DIR . '/plugins/really-simple-ssl-pro/really-simple-ssl-pro.php';
if ( file_exists( $ms_file ) && is_plugin_active('really-simple-ssl-pro-multisite/really-simple-ssl-pro-multisite.php') ) {
$plugin_data = get_plugin_data( $ms_file );
} else if ( file_exists( $pro_file ) && is_plugin_active('really-simple-ssl-pro/really-simple-ssl-pro.php')) {
$plugin_data = get_plugin_data( $pro_file );
}
if ( $plugin_data ) {
$version = $plugin_data['Version'] ?? false;
if ( version_compare( $version, '6.0', '<' ) ) {
REALLY_SIMPLE_SSL::instance()->really_simple_ssl = new really_simple_ssl_legacy();
REALLY_SIMPLE_SSL::instance()->rsssl_mixed_content_fixer = new rsssl_mixed_content_fixer_legacy();
REALLY_SIMPLE_SSL::instance()->rsssl_help = new rsssl_help_legacy();
REALLY_SIMPLE_SSL::instance()->rsssl_multisite = new rsssl_multisite_legacy();
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "really-simple-plugins/really-simple-ssl",
"description": "Really Simple SSL WordPress plugin",
"type": "wordpress-plugin",
"version": "6.2.3",
"require-dev": {
"phpunit/phpunit": "^9",
"yoast/phpunit-polyfills": "^1.0",
"wp-cli/wp-cli-bundle": "^2.7",
"php": ">=7.2",
"composer": "^2.4",
"phpcompatibility/phpcompatibility-wp": "*"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

View File

@@ -0,0 +1,136 @@
<?php
/*
* Deactivation page to simply deactivate the plugin when backend is not accessible anymore
* To deactivate:
* 1) rename this file to force-deactivate.php
* 2) Go in your browser to (note use of http, not https) http://yourdomain.com/wp-content/plugins/really-simple-ssl/force-deactivate.php.
* 3) IMPORTANT! On execution, this file will automatically get renamed to .txt. If you do not run it, don't forget to change it back.
*/
?>
<html>
<body>
<?php
# No need for the template engine
define( 'WP_USE_THEMES', false );
#find the base path
define( 'BASE_PATH', find_wordpress_base_path() . "/" );
# Load WordPress Core
if ( !file_exists(BASE_PATH . 'wp-load.php') ) {
die("WordPress not installed here");
}
//make sure the files are loaded
if (!defined('RSSSL_DOING_SYSTEM_STATUS')) define( 'RSSSL_DOING_SYSTEM_STATUS' , true);
define('RSSSL_LEARNING_MODE', true);
# Load WordPress Core
require_once( BASE_PATH . 'wp-load.php' );
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
rsssl_run_force_deactivate();
function rsssl_run_force_deactivate() {
$core_plugin = 'really-simple-ssl/rlrsssl-really-simple-ssl.php';
if ( ! is_plugin_active( $core_plugin ) ) {
echo "<h1>Really Simple SSL is already deactivated!</h1>";
exit;
}
$step = 1;
echo "<h1>Force deactivation of Really Simple SSL</h1>";
echo $step . ". Resetting options" . "<br>";
//ensure we can run the code
define( 'WP_CLI',true );
RSSSL()->admin->deactivate();
$step ++;
echo $step . ". Deactivating plugin" . "<br>";
rl_deactivate_plugin( RSSSL()->admin->plugin_dir . "/"
. RSSSL()->admin->plugin_filename );
$step ++;
echo $step . ". Completed<b>";
rename('force-deactivate.php' , 'force-deactivate.txt');
}
function rl_remove_plugin_from_array( $plugin, $current ) {
$key = array_search( $plugin, $current );
if ( false !== $key ) {
unset( $current[ $key ] );
}
return $current;
}
function rl_deactivate_plugin( $plugin ) {
$plugin = plugin_basename( trim( $plugin ) );
if ( is_multisite() ) {
$network_current = get_site_option( 'active_sitewide_plugins', array() );
if ( is_plugin_active_for_network( $plugin ) ) {
unset( $network_current[ $plugin ] );
}
update_site_option( 'active_sitewide_plugins', $network_current );
//remove plugin one by one on each site
$args = array(
'public' => 1,
);
$sites = get_sites($args);
foreach ( $sites as $site ) {
switch_to_blog($site->blog_id);
$current = get_option( 'active_plugins', array() );
$current = rl_remove_plugin_from_array( $plugin, $current );
update_option( 'active_plugins', $current );
restore_current_blog(); //switches back to previous blog, not current, so we have to do it each loop
}
} else {
$current = get_option( 'active_plugins', array() );
$current = rl_remove_plugin_from_array( $plugin, $current );
update_option( 'active_plugins', $current );
}
update_option( 'active_plugins', $current );
}
/**
* Helper function to find Wordpress base path.
*/
function find_wordpress_base_path()
{
$path = __DIR__;
do {
if (file_exists($path . "/wp-config.php")) {
//check if the wp-load.php file exists here. If not, we assume it's in a subdir.
if ( file_exists( $path . '/wp-load.php') ) {
return $path;
} else {
//wp not in this directory. Look in each folder to see if it's there.
if ( file_exists( $path ) && $handle = opendir( $path ) ) {
while ( false !== ( $file = readdir( $handle ) ) ) {
if ( $file != "." && $file != ".." ) {
$file = $path .'/' . $file;
if ( is_dir( $file ) && file_exists( $file . '/wp-load.php') ) {
$path = $file;
break;
}
}
}
closedir( $handle );
}
}
return $path;
}
} while ($path = realpath("$path/.."));
return false;
}
?>
</body>
</html>

View File

@@ -0,0 +1,133 @@
<?php
defined('ABSPATH') or die();
/**
* Only functions also required on front-end here
*/
/**
* Get a Really Simple SSL option by name
*
* @param string $name
* @param mixed $default
*
* @return mixed
*/
function rsssl_get_option( string $name, $default=false ) {
$name = sanitize_title($name);
if ( is_multisite() && rsssl_is_networkwide_active() ) {
$options = get_site_option( 'rsssl_options', [] );
} else {
$options = get_option( 'rsssl_options', [] );
}
//fallback, will be removed after 6.2
//because we only check if the option is not saved in the new style, this if should normally never get executed.
if (
!isset($options[$name]) &&
($name === 'ssl_enabled' || $name === 'redirect' || $name === "mixed_content_fixer" || $name === 'dismiss_all_notices' )
) {
$options = rsssl_get_legacy_option($options, $name);
}
$value = $options[ $name ] ?? false;
if ( $value===false && $default!==false ) {
$value = $default;
}
if ($value===1) {
$value = true;
}
return apply_filters("rsssl_option_$name", $value, $name);
}
/**
* Check if we should treat the plugin as networkwide or not.
* Note that this function returns false for single sites! Always use icw is_multisite()
*
* @return bool
*/
function rsssl_is_networkwide_active(){
if ( !is_multisite() ) {
return false;
}
if ( !function_exists('is_plugin_active_for_network') ) {
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
}
if ( is_plugin_active_for_network(rsssl_plugin) ) {
return true;
}
return false;
}
/**
* if the option is does not exist in our new array, check if it's available in the old option. If so, use that one
* @deprecated to be used until 6.2, as fallback for failed upgrades in some specific edge case situations
* @param array|bool $options
* @param string $name
*
* @return array
*/
function rsssl_get_legacy_option( $options, string $name): array {
$old_options = is_multisite() ? get_site_option('rlrsssl_network_options') : get_option( 'rlrsssl_options' );
if ( $old_options ) {
if ( $name === 'ssl_enabled' && isset( $old_options['ssl_enabled']) ) {
$options['ssl_enabled'] = $old_options['ssl_enabled'];
} else if ( $name === 'dismiss_all_notices' && isset( $old_options['dismiss_all_notices']) ) {
$options['dismiss_all_notices'] = $old_options['dismiss_all_notices'];
} else if ( $name === 'dismiss_all_notices' && isset( $old_options['dismiss_all_notices']) ) {
$options['dismiss_all_notices'] = $old_options['dismiss_all_notices'];
} else if ( $name === 'mixed_content_fixer' && isset($old_options['autoreplace_insecure_links']) ) {
$options['mixed_content_fixer'] = $old_options['autoreplace_insecure_links'];
} else if ( $name === 'redirect' ){
if ( isset($old_options['htaccess_redirect']) && $old_options['htaccess_redirect'] ) {
$options['redirect'] = 'htaccess';
} else if (isset($old_options['wp_redirect']) && $old_options['wp_redirect']) {
$options['redirect'] = 'wp_redirect';
}
}
}
return $options;
}
function check_if_email_essential_feature() {
$essential_features = array(
'limit_login_attempts' => rsssl_get_option('enable_limited_login_attempts') == 1,
'two_fa_enabled' => rsssl_get_option('two_fa_enabled') == 1
);
// Check if the current feature is in the essential features array
foreach( $essential_features as $feature => $is_essential ) {
if ( $is_essential ) {
return true;
}
}
return false;
}
/**
* @param $response
* @param $user
* @param $request
*
* @return mixed
*
* Add user roles to /users endpoint
*/
function add_user_role_to_api_response( $response, $user, $request ) {
$headers = $request->get_headers();
if (isset($headers['referer']) && strpos($headers['referer'][0], 'really-simple-security') !== false) {
$data = $response->get_data();
$data['roles'] = $user->roles;
$response->set_data($data);
}
return $response;
}
add_filter('rest_prepare_user', 'add_user_role_to_api_response', 10, 3);

View File

@@ -0,0 +1,48 @@
const gulp = require('gulp');
const rtlcss = require('gulp-rtlcss');
const concat = require('gulp-concat');
const cssbeautify = require('gulp-cssbeautify');
const cssuglify = require('gulp-uglifycss');
const sass = require('gulp-sass')(require('sass'));
const spawn = require('child_process').spawn;
function scssTask(cb) {
// compile scss to css and minify
gulp.src('./assets/css/admin.scss')
.pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError))
.pipe(cssbeautify())
.pipe(gulp.dest('./assets/css'))
.pipe(cssuglify())
.pipe(concat('admin.min.css'))
.pipe(gulp.dest('./assets/css'))
.pipe(rtlcss())
.pipe(gulp.dest('./assets/css/rtl'));
cb();
}
exports.scss = scssTask;
function scssPluginTask(cb) {
// compile scss to css and minify
gulp.src('./assets/css/rsssl-plugin.scss')
.pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError))
.pipe(cssbeautify())
.pipe(gulp.dest('./assets/css'))
.pipe(cssuglify())
.pipe(concat('rsssl-plugin.min.css'))
.pipe(gulp.dest('./assets/css'))
.pipe(rtlcss())
.pipe(gulp.dest('./assets/css/rtl'));
cb();
}
exports.scssPlugin = scssPluginTask;
function defaultTask(cb) {
gulp.watch('./assets/css/**/*.scss', { ignoreInitial: false }, scssTask);
gulp.watch('./assets/css/**/*.scss', { ignoreInitial: false }, scssPluginTask);
spawn('npm', ['start'], { cwd: 'settings', stdio: 'inherit' });
cb();
}
exports.default = defaultTask;

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
<?php defined( 'ABSPATH' ) or die();
if ( ! class_exists( "rsssl_le_restapi" ) ) {
class rsssl_le_restapi{
private static $_this;
function __construct() {
if ( isset( self::$_this ) ) {
wp_die( sprintf( '%s is a singleton class and you cannot create a second instance.',
get_class( $this ) ) );
}
self::$_this = $this;
add_filter("rsssl_run_test", array($this, 'handle_lets_encrypt_request'), 10, 3);
add_action( 'rsssl_after_save_field', array( $this, 'after_save_field' ), 10, 4 );
}
static function this() {
return self::$_this;
}
/**
* Switch to DNS verification
* @param array $data
* @return []
*/
public function update_verification_type($data){
$type = $data['id'];
$type = $type === 'dns' ? 'dns' : 'dir';
rsssl_update_option('verification_type', $type );
if ($type==='dns') {
rsssl_progress_add('directories');
} else {
rsssl_progress_add('dns-verification');
}
return new RSSSL_RESPONSE(
'success',
'stop',
''
);
}
/**
* Skip DNS check
* @return RSSSL_RESPONSE
*/
public function skip_dns_check(){
if ( !rsssl_user_can_manage() ) {
return new RSSSL_RESPONSE(
'error',
'stop',
''
);
}
update_option('rsssl_skip_dns_check', true, false);
return new RSSSL_RESPONSE(
'success',
'stop',
''
);
}
/**
* Get installation data
* @return RSSSL_RESPONSE
*/
public function installation_data(){
if ( !rsssl_user_can_manage() ) {
return new RSSSL_RESPONSE(
'error',
'stop',
''
);
}
$key_file = get_option('rsssl_private_key_path');
$cert_file = get_option('rsssl_certificate_path');
$cabundle_file = get_option('rsssl_intermediate_path');
$data = [
'generated_by_rsssl' => rsssl_generated_by_rsssl(),
'download_url' => rsssl_le_url.'download.php?token='.wp_create_nonce('rsssl_download_cert'),
'key_content' => file_exists($key_file) ? file_get_contents($key_file) : 'no data found',
'certificate_content' => file_exists($cert_file) ? file_get_contents($cert_file) : 'no data found',
'ca_bundle_content' => file_exists($cabundle_file) ? file_get_contents($cabundle_file) : 'no data found',
];
return new RSSSL_RESPONSE(
'success',
'continue',
'',
$data
);
}
/**
* Challenge directory request
*
* @return RSSSL_RESPONSE
*/
public function skip_challenge_directory_request(){
if ( !rsssl_user_can_manage() ) {
return new RSSSL_RESPONSE(
'error',
'stop',
''
);
}
update_option('rsssl_skip_challenge_directory_request', true, false);
return new RSSSL_RESPONSE(
'success',
'stop',
''
);
}
/**
* Reset the LE wizard
* @return bool[]|RSSSL_RESPONSE
*/
public function reset(){
if ( !rsssl_user_can_manage() ) {
return new RSSSL_RESPONSE(
'success',
'stop',
''
);
}
RSSSL_LE()->letsencrypt_handler->clear_order();
rsssl_update_option('verification_type', 'dir' );
delete_option('rsssl_skip_dns_check' );
delete_option('rsssl_skip_challenge_directory_request' );
delete_option('rsssl_create_folders_in_root');
delete_option('rsssl_hosting_dashboard');
RSSSL_LE()->letsencrypt_handler->clear_keys_directory();
return new RSSSL_RESPONSE(
'success',
'stop',
''
);
}
public function clean_up(){
//clean up stored pw, if requested
RSSSL_LE()->letsencrypt_handler->cleanup_on_ssl_activation();
}
/**
* Process a Let's Encrypt test request
*
* @param array $response
* @param string $test
* @param WP_REST_Request $request
*
* @return RSSSL_RESPONSE|array
*/
public function handle_lets_encrypt_request($response, $test, $data){
if ( ! current_user_can('manage_security') ) {
return new RSSSL_RESPONSE(
'error',
'stop',
__( "Permission denied.", 'really-simple-ssl' )
);
}
switch( $test ){
case 'reset':
return $this->reset();
case 'update_verification_type':
return $this->update_verification_type($data);
case 'skip_dns_check':
return $this->skip_dns_check();
case 'skip_challenge_directory_request':
return $this->skip_challenge_directory_request();
case 'installation_data':
return $this->installation_data();
case 'is_subdomain_setup':
case 'verify_dns':
case 'certificate_status':
case 'curl_exists':
case 'server_software':
case 'alias_domain_available':
case 'check_domain':
case 'check_host':
case 'check_challenge_directory':
case 'check_key_directory':
case 'check_certs_directory':
case 'check_writing_permissions':
case 'challenge_directory_reachable':
case 'get_account':
case 'get_dns_token':
case 'terms_accepted':
case 'create_bundle_or_renew':
case 'search_ssl_installation_url':
case 'rsssl_install_cpanel_autossl':
case 'rsssl_cpanel_set_txt_record':
case 'rsssl_install_cpanel_default':
case 'rsssl_cloudways_server_data':
case 'rsssl_cloudways_install_ssl':
case 'rsssl_cloudways_auto_renew':
case 'rsssl_install_directadmin':
case 'rsssl_plesk_install':
case 'cleanup_on_ssl_activation':
return $this->get_installation_progress($response, $test, $data);
default:
return $response;
}
}
/**
* Run a LE test
* @param $response
* @param $function
* @param $data
*
* @return RSSSL_RESPONSE
*/
public function get_installation_progress( $response, $function, $data ){
$id = $data['id'];
if ( ! current_user_can('manage_security') ) {
return new RSSSL_RESPONSE(
'error',
'stop',
__( "Permission denied.", 'really-simple-ssl' )
);
}
if (!function_exists($function) && !method_exists(RSSSL_LE()->letsencrypt_handler, $function)) {
return new RSSSL_RESPONSE(
'error',
'stop',
__( "Test not found.", 'really-simple-ssl' )
);
}
rsssl_progress_add($id);
if ( function_exists($function) ){
$response = $function();
} else {
$response = RSSSL_LE()->letsencrypt_handler->$function();
}
return $response;
}
/**
* Handle some custom options after saving the wizard options
* @param string $field_id
* @param mixed $field_value
* @param mixed $prev_value
* @param string $type
*/
public function after_save_field( $field_id, $field_value, $prev_value, $type ) {
//only run when changes have been made
if ( $field_value === $prev_value ) {
return;
}
if ( $field_id==='other_host_type'){
if ( isset(RSSSL_LE()->hosts->hosts[$field_value]) ){
$dashboard = RSSSL_LE()->hosts->hosts[$field_value]['hosting_dashboard'];
update_option('rsssl_hosting_dashboard', $dashboard, false);
} else {
update_option('rsssl_hosting_dashboard', false, false);
}
}
if ( $field_id === 'email_address'&& is_email($field_value) ) {
RSSSL_LE()->letsencrypt_handler->update_account($field_value);
}
}
}
} //class closure

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
{
"require": {
"fbett/le_acme2": "^1.5",
"plesk/api-php-lib": "^1.0"
}
}

View File

@@ -0,0 +1,581 @@
<?php
defined( 'ABSPATH' ) or die( );
if ( ! class_exists( "rsssl_le_hosts" ) ) {
class rsssl_le_hosts {
private static $_this;
public $steps;
public $hosts;
public $supported_hosts;
public $not_local_certificate_hosts;
public $no_installation_renewal_needed;
public $dashboard_activation_required;
public $activated_by_default;
public $paid_only;
function __construct() {
define('RSSSL_LE_CONFIG_LOADED', true);
if ( isset( self::$_this ) ) {
wp_die( sprintf( '%s is a singleton class and you cannot create a second instance.',
get_class( $this ) ) );
}
self::$_this = $this;
/**
* Plesk requires local SSL generation, and installation renewal.
* Cpanel default requires local SSL generation, and installation renewal.
* Cpanel autossl: no local ssl generation, no renewal
*/
$this->hosts = array(
'cloudways' => array(
'name' => 'CloudWays',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => false,
'hosting_dashboard' => 'cloudways',
'api' => true,
'ssl_installation_link' => false,
),
'tierpoint' => array(
'name' => 'TierPoint',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => true,
'ssl_installation_link' => false,
),
'godaddy' => array(
'name' => 'GoDaddy',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'godaddy_managed' => array(
'name' => 'GoDaddy Managed WordPress',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'godaddymanaged',
'api' => false,
'ssl_installation_link' => false,
),
'kasserver' => array(
'name' => 'Kasserver',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'kasserver',
'api' => false,
'ssl_installation_link' => 'https://kas.all-inkl.com/',
),
'argeweb' => array(
'name' => 'Argeweb',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'plesk',
'api' => false,
'ssl_installation_link' => 'https://www.argeweb.nl/argecs/',
),
'hostgator' => array(
'name' => 'HostGator',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => true,
'hosting_dashboard' => 'cpanel:autossl',
'api' => true,
'ssl_installation_link' => 'https://{host}:2083/frontend/paper_lantern/security/tls_status/',
),
'ionos' => array(
'name' => 'IONOS',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'ionos',
'api' => false,
'ssl_installation_link' => '',
),
'simply' => array(
'name' => 'Simply',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://www.simply.com/en/controlpanel/sslcerts/',
),
'siteground' => array(
'name' => 'SiteGround',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://tools.siteground.com/ssl',
),
'dreamhost' => array(
'name' => 'Dreamhost',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://help.dreamhost.com/hc/en-us/articles/216539548-Adding-a-free-Let-s-Encrypt-certificate',
),
'wpengine' => array(
'name' => 'WPEngine',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://wpengine.com/support/add-ssl-site/#letsencrypt',
),
'ipage' => array(
'name' => 'iPage',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://www.ipage.com/help/article/enable-your-free-ssl-certificate',
),
'onecom' => array(
'name' => 'one.com',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://help.one.com/hc/en-us/articles/360000297458-Why-is-SSL-HTTPS-not-working-on-my-site-',
),
'wpmudev' => array(
'name' => 'WPMUDEV',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => false,
'api' => false,
'ssl_installation_link' => 'https://wpmudev.com',
),
'ovh' => array(
'name' => 'OVH',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => 'https://ovh.com',
),
'bluehost' => array(
'name' => 'BlueHost',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => 'https://www.bluehost.com/help/article/how-to-activate-a-free-wordpress-ssl',
),
'freeola' => array(
'name' => 'Freeola',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'freeola',
'api' => false,
'ssl_installation_link' => '',
),
'hostinger' => array(
'name' => 'Hostinger',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'hpanel',
'api' => false,
'ssl_installation_link' => 'https://hpanel.hostinger.com/hosting/{domain}advanced/ssl',
),
'pcextreme' => array(
'name' => 'PCExtreme',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'directadmin',
'api' => false,
'ssl_installation_link' => 'https://help.pcextreme.nl/domains-ssl/hoe-vraag-ik-een-ssl-certificaat-aan-voor-mijn-domein/',
),
'internic' => array(
'name' => 'Internic',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'internic',
'api' => false,
'ssl_installation_link' => 'https://internic.com',
),
'aruba' => array(
'name' => 'Aruba',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'aruba',
'api' => false,
'ssl_installation_link' => 'https://admin.aruba.it/PannelloAdmin/UI/Pages/ContentSection.aspx?Action=153',
),
'namecheap' => array(
'name' => 'Namecheap',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => 'https://www.namecheap.com/blog/install-free-ssls/',
),
'hostpapa' => array(
'name' => 'Hostpapa',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'webcom' => array(
'name' => 'web.com',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'web.com',
'api' => false,
'ssl_installation_link' => false,
),
'crazydomains' => array(
'name' => 'Crazydomains',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'crazydomains',
'api' => false,
'ssl_installation_link' => false,
),
'strato' => array(
'name' => 'Strato',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'plesk',
'api' => false,
'ssl_installation_link' => false,
),
'inmotion' => array(
'name' => 'Inmotion',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => 'https://www.inmotionhosting.com/support/website/ssl/auto-ssl-guide/',
),
'flywheel' => array(
'name' => 'Flywheel',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'flywheel',
'api' => false,
'ssl_installation_link' => 'https://getflywheel.com/why-flywheel/simple-ssl/',
),
'kinsta' => array(
'name' => 'Kinsta',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'mykinsta',
'api' => false,
'ssl_installation_link' => false,
),
'pressable' => array(
'name' => 'Pressable',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'pressable',
'api' => false,
'ssl_installation_link' => false,
),
'wpx' => array(
'name' => 'WPX',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'wpx',
'api' => false,
'ssl_installation_link' => false,
),
'greengeeks' => array(
'name' => 'Greengeeks',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'greengeeks',
'api' => false,
'ssl_installation_link' => 'https://www.greengeeks.com/support/article/getting-started-adding-lets-encrypt-ssl-greengeeks-account/',
),
'liquidweb' => array(
'name' => 'Liquidweb',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'profreehost' => array(
'name' => 'Profreehost',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => 'https://profreehost.com/support/ssl-https/how-to-install-an-ssl-certificate/',
),
'hostdash' => array(
'name' => 'Hostdash',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'byethost' => array(
'name' => 'Byethost',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'byethost',
'api' => false,
'ssl_installation_link' => false,
),
'site5' => array(
'name' => 'Site5',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => '',
),
'epizy' => array(
'name' => 'Epizy',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => '',
),
'infinityfree' => array(
'name' => 'Infinityfree',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => '',
),
'gandi' => array(
'name' => 'Gandi',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'gandi',
'api' => false,
'ssl_installation_link' => false,
),
'contabo' => array(
'name' => 'Contabo',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => true,
'hosting_dashboard' => 'cpanel:autossl',
'api' => true,
'ssl_installation_link' => 'https://{host}:2083/frontend/paper_lantern/security/tls_status/',
),
'earthlink' => array(
'name' => 'Earthlink',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => true,
'ssl_installation_link' => false,
),
'hostway' => array(
'name' => 'Hostway',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'beget' => array(
'name' => 'Beget',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'beget',
'api' => false,
'ssl_installation_link' => false,
),
'fatcow' => array(
'name' => 'Fatcow',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'fatcow',
'api' => false,
'ssl_installation_link' => false,
),
'ventraip' => array(
'name' => 'Ventraip',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activated_by_default',
'hosting_dashboard' => 'cpanel:autossl',
'api' => false,
'ssl_installation_link' => 'https://{host}:2083/frontend/paper_lantern/security/tls_status/',
),
'namescouk' => array(
'name' => 'Names.co.uk',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'mediatemple' => array(
'name' => 'Mediatemple',
'installation_renewal_required' => true,
'local_ssl_generation_needed' => true,
'free_ssl_available' => false,
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'digitalocean' => array(
'name' => 'Digitalocean',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'digitalocean',
'api' => false,
'ssl_installation_link' => 'https://docs.digitalocean.com/products/accounts/security/certificates/',
),
'fisthost' => array(
'name' => 'Fisthost',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'fisthost',
'api' => false,
'ssl_installation_link' => 'https://my.fisthost.com/knowledgebase/6/How-do-I-activate-my-free-SSL.html',
),
'register' => array(
'name' => 'register.lk',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'paid_only',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => '',
),
'fasthosts' => array(
'name' => 'Fasthosts',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'cpanel',
'api' => false,
'ssl_installation_link' => false,
),
'upress' => array(
'name' => 'Upress',
'installation_renewal_required' => false,
'local_ssl_generation_needed' => false,
'free_ssl_available' => 'activation_required',
'hosting_dashboard' => 'false',
'api' => false,
'ssl_installation_link' => 'https://support.upress.io',
),
);
$this->not_local_certificate_hosts = $this->filter_hosts( 'local_ssl_generation_needed', false);
$this->dashboard_activation_required = $this->filter_hosts( 'free_ssl_available', 'activation_required');
$this->activated_by_default = $this->filter_hosts( 'free_ssl_available', 'activated_by_default');
$this->paid_only = $this->filter_hosts( 'free_ssl_available', 'paid_only');
$this->no_installation_renewal_needed = $this->filter_hosts( 'installation_renewal_required', false);
$this->no_installation_renewal_needed[] = 'cpanel:autossl';
ksort($this->hosts);
$this->supported_hosts = array(
'none' => __('I don\'t know, or not listed, proceed with installation', 'really-simple-ssl'),
);
$this->supported_hosts = $this->supported_hosts + wp_list_pluck($this->hosts, 'name');
}
static function this() {
return self::$_this;
}
/**
* @param array $array
* @param mixed $filter_value
* @param mixed $filter_key
*
* @return array
*/
public function filter_hosts( $filter_key, $filter_value){
return array_keys(array_filter($this->hosts, function ($var) use ($filter_value, $filter_key) {
return ($var[$filter_key] == $filter_value);
}) );
}
/**
* @param string | bool $type
*
* @return bool
*/
public function host_api_supported( $type ) {
$hosting_company = rsssl_get_other_host();
//if not listed, we assume it can.
if ( !$hosting_company || $hosting_company === 'none' ) {
return true;
}
$hosts_has_dashboard = RSSSL_LE()->hosts->filter_hosts( 'api', $type);
if ( in_array($hosting_company, $hosts_has_dashboard) ) {
return true;
} else {
return false;
}
}
}
} //class closure

View File

@@ -0,0 +1,580 @@
<?php
function rsssl_le_steps(){
$steps =
[
[
"id" => "system-status",
"title" => __( "System Status", 'really-simple-ssl' ),
],
[
"id" => "domain",
"title" => __( "General settings", 'really-simple-ssl' ),
],
[
"id" => "directories",
"title" => __( "Directories", 'really-simple-ssl' ),
],
[
"id" => "dns-verification",
"title" => __( "DNS Verification", 'really-simple-ssl' ),
],
[
"id" => "generation",
"title" => __( "Generation", 'really-simple-ssl' ),
],
[
"id" => "installation",
"title" => __( "Installation", 'really-simple-ssl' ),
],
];
return $steps;
}
/**
* Let's Encrypt
*/
add_filter("rsssl_fields", "rsssl_le_add_fields");
function rsssl_le_add_fields($fields) {
$fields = array_merge($fields, [
[
'id' => 'system-status',
'menu_id' => 'le-system-status',
'group_id' => 'le-system-status',
"intro" => __( "Detected status of your setup.", "really-simple-ssl" ),
'type' => 'letsencrypt',
'default' => false,
'actions' => [
[
'description' => __( "Checking SSL certificate...", "really-simple-ssl" ),
'action' => 'certificate_status',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking if CURL is available...", "really-simple-ssl" ),
'action' => 'curl_exists',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking server software...", "really-simple-ssl" ),
'action' => 'server_software',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking alias domain...", "really-simple-ssl" ),
'action' => 'alias_domain_available',
'attempts' => 3,
'status' => 'inactive',
],
[
'description' => __( "Checking for website configuration...", "really-simple-ssl" ),
'action' => 'check_domain',
'attempts' => 1,
'status' => 'inactive',
],
],
],
[
'id' => 'verification_type',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'type' => 'hidden',
],
[
'id' => 'email_address',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'type' => 'email',
'label' => __( "Email address", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "Email address", "really-simple-ssl" ),
'text' => __( "This email address is used to create a Let's Encrypt account. This is also where you will receive renewal notifications.", 'really-simple-ssl' ),
],
'default' => '',
'required' => true,
],
[
'id' => 'accept_le_terms',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'type' => 'checkbox',
'default' => false,
'required' => true,
'label' => __( 'I agree to the Terms & Conditions from Let\'s Encrypt.','really-simple-ssl'),
'comment' => '<a target="_blank" href="https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf">'.__('Terms & Conditions.', "really-simple-ssl" ).'</a>',
],
[
'id' => 'disable_ocsp',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'required'=> false,
'type' => 'checkbox',
'default' => false,
'help' => [
'label' => 'default',
'url' => 'https://really-simple-ssl.com/ocsp-stapling',
'title' => __( "Disable OCSP stapling", "really-simple-ssl" ),
'text' => __( "OCSP stapling is configured as enabled by default. You can disable this option if this is not supported by your hosting provider.", "really-simple-ssl" ),
],
'label' => __( "Disable OCSP Stapling", 'really-simple-ssl' ),
],
[
'id' => 'domain',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'type' => 'text',
'default' => rsssl_get_domain(),
'label' => __( "Domain", 'really-simple-ssl' ),
'required' => false,
'disabled' => true,
],
[
'id' => 'include_alias',
'menu_id' => 'le-general',
'group_id' => 'le-general',
'type' => 'checkbox',
'default' => '',
'label' => __( "Include alias", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "Include alias", "really-simple-ssl" ),
'text' => __( "This will include both the www. and non-www. version of your domain.", "really-simple-ssl" ) . ' '
. __( "You should have the www domain pointed to the same website as the non-www domain.", 'really-simple-ssl' ),
],
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_subdomain()' => false,
'rsssl_wildcard_certificate_required()' => false,
]
],
],
[
'id' => 'other_host_type',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'host',
'options' => RSSSL_LE()->hosts->supported_hosts,
'help' => [
'label' => 'default',
'title' => __( "Hosting Provider", "really-simple-ssl" ),
'text' => __( "By selecting your hosting provider we can tell you if your hosting provider already supports free SSL, and/or where you can activate it.", "really-simple-ssl" )
. "&nbsp;" .
sprintf( __( "If your hosting provider is not listed, and there's an SSL activation/installation link, please let us %sknow%s.", "really-simple-ssl" ),
'<a target="_blank" href="https://really-simple-ssl.com/install-ssl-certificate/#hostingdetails">', '</a>' ),
],
'default' => false,
'label' => __( "Hosting provider", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
],
[
'id' => 'cpanel_host',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "CPanel host", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "CPanel host", "really-simple-ssl" ),
'text' => __( "The URL you use to access your cPanel dashboard. Ends on :2083.", 'really-simple-ssl' ),
],
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_cpanel()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'cpanel_username',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "CPanel username", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_cpanel_api_supported()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'cpanel_password',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'password',
'default' => '',
'label' => __( "CPanel password", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_cpanel_api_supported()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'directadmin_host',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "DirectAdmin host", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "Direct Admin URL", "really-simple-ssl" ),
'text' => __( "The URL you use to access your DirectAdmin dashboard. Ends on :2222.", 'really-simple-ssl' ),
],
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_directadmin()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'directadmin_username',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "DirectAdmin username", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_directadmin()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'directadmin_password',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'password',
'default' => '',
'label' => __( "DirectAdmin password", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_directadmin()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'cloudways_user_email',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'placeholder' => 'email@email.com',
'label' => __( "CloudWays user email", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'other_host_type' => 'cloudways',
]
],
],
[
'id' => 'cloudways_api_key',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'password',
'default' => '',
'label' => __( "CloudWays api key", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'help' => [
'label' => 'default',
'title' => __( "CloudWays API key", "really-simple-ssl" ),
'text' => sprintf( __( "You can find your api key %shere%s (make sure you're logged in with your main account).", "really-simple-ssl" ),
'<a target="_blank" href="https://platform.cloudways.com/api">', '</a>' ),
],
'server_conditions' => [
'relation' => 'AND',
[
'other_host_type' => 'cloudways',
]
],
],
[
'id' => 'plesk_host',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "Plesk host", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "Plesk admin URL", "really-simple-ssl" ),
'text' => __( "The URL you use to access your Plesk dashboard. Ends on :8443.", 'really-simple-ssl' ),
],
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_plesk()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'plesk_username',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'text',
'default' => '',
'label' => __( "Plesk username", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => __( "Plesk username and password", "really-simple-ssl" ),
'text' => sprintf( __( "You can find your Plesk username and password in %s", 'really-simple-ssl' ), 'https://{your-plesk-host-name}:8443/smb/my-profile' ),
],
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_plesk()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'plesk_password',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'password',
'default' => '',
'label' => __( "Plesk password", 'really-simple-ssl' ),
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_is_plesk()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'store_credentials',
'menu_id' => 'le-hosting',
'group_id' => 'le-hosting',
'type' => 'checkbox',
'default' => '',
'label' => __( "Do you want to store these credentials for renewal purposes?", 'really-simple-ssl' ),
'help' => [
'label' => 'default',
'title' => 'Storing credentials',
'text' => __( "Store for renewal purposes. If not stored, renewal may need to be done manually.", 'really-simple-ssl' ),
],
'required' => false,
'disabled' => false,
'server_conditions' => [
'relation' => 'AND',
[
'rsssl_uses_known_dashboard()' => true,
'rsssl_activated_by_default()' => false,
'rsssl_activation_required()' => false,
'rsssl_paid_only()' => false,
]
],
],
[
'id' => 'directories',
'menu_id' => 'le-directories',
'group_id' => 'le-directories',
'condition_action' => 'hide',
'type' => 'letsencrypt',
'actions' => [
[
'description' => __( "Checking host...", "really-simple-ssl" ),
'action' => 'check_host',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking challenge directory...", "really-simple-ssl" ),
'action' => 'check_challenge_directory',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking key directory...", "really-simple-ssl" ),
'action' => 'check_key_directory',
'attempts' => 2,
'status' => 'inactive',
],
[
'description' => __( "Checking certs directory...", "really-simple-ssl" ),
'action' => 'check_certs_directory',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking permissions...", "really-simple-ssl" ),
'action' => 'check_writing_permissions',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __( "Checking challenge directory reachable over http...", "really-simple-ssl" ),
'action' => 'challenge_directory_reachable',
'attempts' => 1,
'status' => 'inactive',
],
],
'react_conditions' => [
'relation' => 'AND',
[
'!verification_type' => 'dns',
]
],
],
[
'id' => 'dns-verification',
'menu_id' => 'le-dns-verification',
'group_id' => 'le-dns-verification',
'type' => 'letsencrypt',
'condition_action' => 'hide',
'actions' => [
[
'description' => __("Creating account...", "really-simple-ssl"),
'action'=> 'get_account',
'attempts' => 5,
'status' => 'inactive',
],
[
'description' => __("Retrieving DNS verification token...", "really-simple-ssl"),
'action'=> 'get_dns_token',
'attempts' => 5,
'status' => 'inactive',
],
],
'react_conditions' => [
'relation' => 'AND',
[
'verification_type' => 'dns',
]
],
],
[
'id' => 'generation',
'menu_id' => 'le-generation',
'group_id' => 'le-generation',
'type' => 'letsencrypt',
// 'server_conditions' => [
// 'relation' => 'AND',
// [
// 'rsssl_do_local_lets_encrypt_generation' => true,
// ]
// ],
'actions' => [
[
'description' => __("Checking if Terms & Conditions are accepted...", "really-simple-ssl"),
'action'=> 'terms_accepted',
'attempts' => 1,
'status' => 'inactive',
],
[
'description' => __("Creating account...", "really-simple-ssl"),
'action'=> 'get_account',
'attempts' => 5,
'status' => 'inactive',
],
[
'description' => __("Generating SSL certificate...", "really-simple-ssl"),
'action'=> 'create_bundle_or_renew',
'attempts' => 5,
'status' => 'inactive',
],
],
],
[
'id' => 'installation',
'menu_id' => 'le-installation',
'group_id' => 'le-installation',
'type' => 'letsencrypt',
'actions' => [
[
'description' => __("Searching for link to SSL installation page on your server...", "really-simple-ssl"),
'action'=> 'search_ssl_installation_url',
'attempts' => 1,
'status' => 'inactive',
],
],
],
[
'id' => 'activate_ssl',
'menu_id' => 'le-activate_ssl',
'group_id' => 'le-activate_ssl',
'type' => 'activate',
],
]);
if ( is_multisite() ) {
$index = array_search( 'system-status', array_column( $fields, 'id' ) );
$new_test = [
'description' => __( "Checking for subdomain setup...", "really-simple-ssl" ),
'action' => 'is_subdomain_setup',
'attempts' => 1,
'status' => 'inactive',
];
$current_tests = $fields[ $index ]['actions'];
$current_tests[] = $new_test;
$fields[ $index ]['actions'] = $current_tests;
}
return $fields;
}

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

View File

@@ -0,0 +1,179 @@
<?php
/**
* Show notice if certificate needs to be renewed.
*
* @param array $notices
*
* @return array
*/
function rsssl_le_get_notices_list($notices) {
//these notices are also loaded if Lets Encrypt is not loaded. To prevent errors, notices which require LE functionality are not loaded
if ( rsssl_generated_by_rsssl() && rsssl_letsencrypt_generation_allowed() ) {
//expiration date requests are cached.
$valid = RSSSL()->certificate->is_valid();
$certinfo = get_transient( 'rsssl_certinfo' );
$end_date = isset( $certinfo['validTo_time_t'] ) ? $certinfo['validTo_time_t'] : false;
//if the certificate expires within the grace period, allow renewal
//e.g. expiry date 30 may, now = 10 may => grace period 9 june.
$expiry_date = ! empty( $end_date ) ? date( get_option( 'date_format' ), $end_date ) : false;
if ( get_option( 'rsssl_create_folders_in_root' ) ) {
if ( ! get_option( 'rsssl_htaccess_file_set_key' ) || ! get_option( 'rsssl_htaccess_file_set_certs' ) || ! get_option( 'rsssl_htaccess_file_set_ssl' ) ) {
$notices['root_files_not_protected'] = array(
'condition' => array( 'rsssl_ssl_enabled' ),
'callback' => '_true_',
'score' => 10,
'output' => array(
'true' => array(
'msg' => __( "Your Key and Certificate directories are not properly protected.", "really-simple-ssl" ),
'url' => "https://really-simple-ssl.com/protect-ssl-generation-directories",
'icon' => 'warning',
'plusone' => true,
'dismissible' => true,
),
),
);
}
}
if ( strpos(site_url(), 'www.') !== false ) {
$text = __( "The non-www version of your site does not point to this website. This is recommended, as it will allow you to add it to the certificate as well.", 'really-simple-ssl' );
} else {
$text = __( "The www version of your site does not point to this website. This is recommended, as it will allow you to add it to the certificate as well.", 'really-simple-ssl' );
}
$notices['alias_domain_notice'] = array(
'condition' => array( 'NOT rsssl_is_subdomain' ),
'callback' => 'RSSSL_LE()->letsencrypt_handler->alias_domain_available',
'score' => 10,
'output' => array(
'false' => array(
'title' => __( "Domain", 'really-simple-ssl' ),
'msg' => $text,
'icon' => 'open',
'plusone' => true,
'dismissible' => true,
),
),
'show_with_options' => [
'domain',
]
);
if ( $expiry_date ) {
$notices['ssl_detected'] = array(
'condition' => array( 'rsssl_ssl_enabled' ),
'callback' => 'RSSSL()->certificate->about_to_expire',
'score' => 10,
'output' => array(
'false' => array(
'msg' => sprintf( __( "Your certificate is valid until: %s", "really-simple-ssl" ), $expiry_date ),
'icon' => 'success'
),
'true' => array(
'msg' => sprintf( __( "Your certificate will expire on %s. You can renew it %shere%s.", "really-simple-ssl" ), $expiry_date, '<a href="' . rsssl_letsencrypt_wizard_url() . '">', '</a>' ),
'icon' => 'open',
'plusone' => true,
'dismissible' => false,
),
),
);
}
$notices['certificate_installation'] = array(
'condition' => array( 'rsssl_ssl_enabled', 'RSSSL()->certificate->about_to_expire' ),
'callback' => 'RSSSL_LE()->letsencrypt_handler->certificate_renewal_status_notice',
'score' => 10,
'output' => array(
'automatic-installation-failed' => array(
'msg' => sprintf( __( "The automatic installation of your certificate has failed. Please check your credentials, and retry the %sinstallation%s.",
"really-simple-ssl" ), '<a href="' . rsssl_letsencrypt_wizard_url() . '">', '</a>' ),
'icon' => 'open',
'plusone' => true,
'dismissible' => false,
),
'manual-installation' => array(
'msg' => sprintf( __( "The SSL certificate has been renewed, and requires manual %sinstallation%s in your hosting dashboard.", "really-simple-ssl" ),
'<a href="' . rsssl_letsencrypt_wizard_url('le-installation') . '">', '</a>' ),
'icon' => 'open',
'plusone' => true,
'dismissible' => false,
),
'manual-generation' => array(
'msg' => sprintf( __( "Automatic renewal of your certificate was not possible. The SSL certificate should be %srenewed%s manually.", "really-simple-ssl" ),
'<a href="' . rsssl_letsencrypt_wizard_url() . '">', '</a>' ),
'icon' => 'open',
'plusone' => true,
'dismissible' => false,
),
'automatic' => array(
'msg' => __( "Your certificate will be renewed and installed automatically.", "really-simple-ssl" ),
'icon' => 'open',
'plusone' => true,
'dismissible' => false,
),
),
);
}
//we run these notices only if the cert is generated by rsssl, or it's not valid.
if ( rsssl_generated_by_rsssl() || !RSSSL()->certificate->is_valid() ) {
$notices['can_use_shell'] = array(
'condition' => array('rsssl_can_install_shell_addon'),
'callback' => '_true_',
'score' => 10,
'output' => array(
'true' => array(
'msg' => __( "Your server provides shell functionality, which offers additional methods to install SSL. If installing SSL using the default methods is not possible, you can install the shell add on.", "really-simple-ssl" ),
'icon' => 'open',
'url' => "https://really-simple-ssl.com/installing-ssl-using-shell-functions",
'plusone' => true,
'dismissible' => true,
),
),
);
//show notice if the shell exec add on is not up to date
if ( function_exists('rsssl_le_load_shell_addon') && defined('rsssl_shell_version') && version_compare(rsssl_shell_version,'2.0.0','<')){
$notices['old_shell_exec_plugin'] = array(
'callback' => '_true_',
'score' => 10,
'output' => array(
'true' => array(
'msg' => __( "You are using the Really Simple SSL Shell Exec add on, but your current version needs to be updated.", "really-simple-ssl" ),
'icon' => 'warning',
'url' => "https://really-simple-ssl.com/installing-ssl-using-shell-functions",
'plusone' => true,
'dismissible' => false,
),
),
);
}
}
return $notices;
}
add_filter( 'rsssl_notices', 'rsssl_le_get_notices_list', 30, 1 );
/**
* Replace the go pro or scan button with a renew SSL button when the cert should be renewed.
*/
function rsssl_le_progress_footer_renew_ssl($button){
if ( rsssl_ssl_enabled() && RSSSL()->certificate->about_to_expire() ){
$status = RSSSL_LE()->letsencrypt_handler->certificate_renewal_status_notice;
switch ($status){
case 'manual-installation':
$button_text = __("Renew installation", "really-simple-ssl");
break;
case 'manual-generation':
$button_text = __("Renew certificate", "really-simple-ssl");
break;
default:
$button_text = __("Renew certificate", "really-simple-ssl");//false;
}
if ($button_text) {
$url = rsssl_letsencrypt_wizard_url();
$button = '<a href="'.$url.'" class="button button-default">'.$button_text.'</a>';
}
}
return $button;
}
add_filter("rsssl_progress_footer_right", "rsssl_le_progress_footer_renew_ssl", 30);

View File

@@ -0,0 +1,99 @@
<?php
defined( 'ABSPATH' ) or die();
add_action( 'plugins_loaded', 'rsssl_le_schedule_cron' );
function rsssl_le_schedule_cron() {
//only run if SSL is enabled.
if ( !rsssl_get_option('ssl_enabled') ) {
return;
}
//only if generated by RSSSL.
if ( ! get_option( 'rsssl_le_certificate_generated_by_rsssl' ) ) {
return;
}
$useCron = true;
if ( $useCron ) {
if ( ! wp_next_scheduled( 'rsssl_le_every_week_hook' ) ) {
wp_schedule_event( time(), 'rsssl_le_weekly', 'rsssl_le_every_week_hook' );
}
if ( ! wp_next_scheduled( 'rsssl_le_every_day_hook' ) ) {
wp_schedule_event( time(), 'rsssl_le_daily', 'rsssl_le_every_day_hook' );
}
add_action( 'rsssl_le_every_week_hook', 'rsssl_le_cron_maybe_start_renewal' );
add_action( 'rsssl_le_every_day_hook', 'rsssl_le_check_renewal_status' );
} else {
add_action( 'init', 'rsssl_le_cron_maybe_start_renewal' );
add_action( 'init', 'rsssl_le_check_renewal_status' );
}
}
/**
* Check if the certificate is generated by RSSSL. If so, renew if necessary
*/
function rsssl_le_cron_maybe_start_renewal(){
if ( !rsssl_generated_by_rsssl() ) {
return;
}
if ( RSSSL_LE()->letsencrypt_handler->cron_certificate_needs_renewal() ) {
update_option("rsssl_le_start_renewal", true, false);
}
if ( RSSSL_LE()->letsencrypt_handler->certificate_install_required() ) {
update_option("rsssl_le_start_installation", true, false);
}
}
function rsssl_le_check_renewal_status(){
if ( !rsssl_generated_by_rsssl() ) {
return;
}
//when DNS validated, without api, we cannot autorenew
if ( !RSSSL_LE()->letsencrypt_handler->ssl_generation_can_auto_renew() ) {
return;
}
$renewal_active = get_option("rsssl_le_start_renewal");
$installation_active = get_option("rsssl_le_start_installation");
if ( $renewal_active ) {
RSSSL_LE()->letsencrypt_handler->create_bundle_or_renew();
} else if ( $installation_active ) {
RSSSL_LE()->letsencrypt_handler->cron_renew_installation();
}
}
add_filter( 'cron_schedules', 'rsssl_le_filter_cron_schedules' );
function rsssl_le_filter_cron_schedules( $schedules ) {
$schedules['rsssl_le_weekly'] = array(
'interval' => WEEK_IN_SECONDS,
'display' => __( 'Once every week' )
);
$schedules['rsssl_le_daily'] = array(
'interval' => DAY_IN_SECONDS,
'display' => __( 'Once every day' )
);
$schedules['rsssl_le_five_minutes'] = array(
'interval' => 5 * MINUTE_IN_SECONDS,
'display' => __( 'Once every 5 minutes' )
);
return $schedules;
}
register_deactivation_hook( rsssl_file, 'rsssl_le_clear_scheduled_hooks' );
function rsssl_le_clear_scheduled_hooks() {
wp_clear_scheduled_hook( 'rsssl_le_every_week_hook' );
wp_clear_scheduled_hook( 'rsssl_le_every_day_hook' );
}

View File

@@ -0,0 +1,109 @@
<?php
# No need for the template engine
define( 'WP_USE_THEMES', false );
#find the base path
define( 'BASE_PATH', rsssl_find_wordpress_base_path()."/" );
# Load WordPress Core
if ( !file_exists(BASE_PATH . 'wp-load.php') ) {
die("WordPress not installed here");
}
require_once( BASE_PATH.'wp-load.php' );
require_once( ABSPATH.'wp-includes/class-phpass.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
if ( !rsssl_user_can_manage() ) {
die();
}
if ( !isset($_GET["type"]) ) {
die();
}
if (!isset($_GET['token'])) {
die();
}
if (!wp_verify_nonce($_GET['token'], 'rsssl_download_cert')){
die();
}
$type = sanitize_title($_GET['type']);
switch($type) {
case 'certificate':
$file = get_option('rsssl_certificate_path');
$file_name = 'certificate.cert';
break;
case 'private_key':
$file = get_option('rsssl_private_key_path');
$file_name = 'private.pem';
break;
case 'intermediate':
$file = get_option('rsssl_intermediate_path');
$file_name = 'intermediate.pem';
break;
default:
$file = false;
}
if (!file_exists($file)) {
$content = __("File missing. Please retry the previous steps.", "really-simple-ssl");
die();
} else {
$content = file_get_contents($file);
}
$fp = fopen($file, 'rb');
if ($fp) {
if (function_exists('mb_strlen')) {
$fsize = mb_strlen($content, '8bit');
} else {
$fsize = strlen($content);
}
$path_parts = pathinfo($file);
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=\"".$file_name."\"");
header("Content-length: $fsize");
header("Cache-Control: private",false); // required for certain browsers
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Transfer-Encoding: binary");
echo $content;
} else {
echo "Something went wrong #2";
}
fclose($fp);
function rsssl_find_wordpress_base_path()
{
$path = dirname(__FILE__);
do {
if (file_exists($path . "/wp-config.php")) {
//check if the wp-load.php file exists here. If not, we assume it's in a subdir.
if ( file_exists( $path . '/wp-load.php') ) {
return $path;
} else {
//wp not in this directory. Look in each folder to see if it's there.
if ( file_exists( $path ) && $handle = opendir( $path ) ) {
while ( false !== ( $file = readdir( $handle ) ) ) {
if ( $file != "." && $file != ".." ) {
$file = $path .'/' . $file;
if ( is_dir( $file ) && file_exists( $file . '/wp-load.php') ) {
$path = $file;
break;
}
}
}
closedir( $handle );
}
}
return $path;
}
} while ($path = realpath("$path/.."));
return false;
}

View File

@@ -0,0 +1,584 @@
<?php defined( 'ABSPATH' ) or die();
/**
* Create a generic read more text with link for help texts.
*
* @param string $url
* @param bool $add_space
*
* @return string
*/
function rsssl_le_read_more( $url, $add_character = ' ' ) {
$html = sprintf( __( "For more information, please read this %sarticle%s",
'really-simple-ssl' ), '<a target="_blank" href="' . $url . '">',
'</a>' );
if ( is_string($add_character) ) {
$html = $add_character . $html;
}
return $html;
}
/**
* Check if we need to use DNS verification
* @return bool
*/
function rsssl_dns_verification_required(){
/**
* If our current hosting provider does not allow or require local SSL certificate generation,
* We do not need to DNS verification either.
*/
if ( !rsssl_do_local_lets_encrypt_generation() ) {
return false;
}
if ( rsssl_get_option('verification_type')==='dns' ) {
return true;
}
if ( rsssl_wildcard_certificate_required() ) {
return true;
}
return false;
}
if ( !function_exists('rsssl_is_cpanel')) {
/**
* Check if we're on CPanel
*
* @return bool
*/
function rsssl_is_cpanel() {
$open_basedir = ini_get("open_basedir");
if ( empty($open_basedir) && file_exists( "/usr/local/cpanel" ) ) {
return true;
} else if (rsssl_check_port(2082)) {
return true;
} else {
return false;
}
}
}
if (!function_exists('rsssl_cpanel_api_supported')) {
/**
* Check if CPanel supports the api
*
* @return bool
*/
function rsssl_cpanel_api_supported() {
if ( rsssl_is_cpanel() ) {
return true;
}
return !rsssl_openbasedir_restriction("/usr/local/cpanel/php/cpanel.php") && file_exists( "/usr/local/cpanel/php/cpanel.php" );
}
}
if (!function_exists('rsssl_activated_by_default')) {
/**
* Check if the host has ssl, activated by default
*
* @return bool
*/
function rsssl_activated_by_default() {
$activated_by_default = false;
$activated_by_default_hosts = RSSSL_LE()->hosts->activated_by_default;
$current_host = rsssl_get_other_host();
if ( in_array( $current_host, $activated_by_default_hosts ) ) {
$activated_by_default = true;
}
return $activated_by_default;
}
}
if ( !function_exists('rsssl_openbasedir_restriction')) {
function rsssl_openbasedir_restriction( string $path): bool {
// Default error handler is required
set_error_handler(null);
// Clean last error info.
error_clear_last();
// Testing...
@file_exists($path);
// Restore previous error handler
restore_error_handler();
// Return `true` if error has occurred
return ($error = error_get_last()) && $error['message'] !== '__clean_error_info';
}
}
if (!function_exists('rsssl_activation_required')) {
/**
* Check if the host has ssl, activation required
*
* @return bool
*/
function rsssl_activation_required() {
$dashboard_activation_required = false;
$dashboard_activation_required_hosts = RSSSL_LE()->hosts->dashboard_activation_required;
$current_host = rsssl_get_other_host();
if ( in_array( $current_host, $dashboard_activation_required_hosts ) ) {
$dashboard_activation_required = true;
}
return $dashboard_activation_required;
}
}
if (!function_exists('rsssl_paid_only')) {
/**
* Check if the host has ssl, paid only
*
* @return bool
*/
function rsssl_paid_only() {
$paid_only = false;
$paid_only_hosts = RSSSL_LE()->hosts->paid_only;
$current_host = rsssl_get_other_host();
if ( in_array( $current_host, $paid_only_hosts ) ) {
$paid_only = true;
}
return $paid_only;
}
}
if ( !function_exists('rsssl_is_plesk')) {
/**
* https://stackoverflow.com/questions/26927248/how-to-detect-servers-control-panel-type-with-php
* @return false
*/
function rsssl_is_plesk() {
if ( get_option('rsssl_hosting_dashboard')==='plesk' ){
return true;
}
//cpanel takes precedence, as it's more precise
if ( rsssl_is_cpanel() ) {
return false;
}
$open_basedir = ini_get("open_basedir");
if ( empty($open_basedir) && is_dir( '/usr/local/psa' ) ) {
return true;
} else if (rsssl_check_port(8443)) {
return true;
} else {
return false;
}
}
}
if ( !function_exists('rsssl_is_directadmin')) {
/**
* https://stackoverflow.com/questions/26927248/how-to-detect-servers-control-panel-type-with-php
* @return bool
*/
function rsssl_is_directadmin() {
if ( get_option('rsssl_hosting_dashboard')==='directadmin' ){
return true;
}
//cpanel takes precedence, as it's more precise
if ( rsssl_is_cpanel() ) {
return false;
}
if ( rsssl_is_plesk() ) {
return false;
}
if (rsssl_check_port(2222)) {
return true;
} else {
return false;
}
}
}
/**
* @param int $port
*
* @return bool
*/
function rsssl_check_port( $port)
{
$port_check_status = get_option("rsssl_port_check_$port");
if ( !function_exists('fsockopen') || $port_check_status === 'fail' ) {
return false;
}
$ipAddress = gethostbyname('localhost');
$link = @fsockopen( $ipAddress, $port, $errno, $error, 5 );
if ( $link ) {
update_option("rsssl_port_check_$port", 'success', false);
return true;
}
update_option("rsssl_port_check_$port", 'fail', false);
return false;
}
if ( !function_exists('rsssl_get_other_host') ) {
/**
* Get the selected hosting provider, if any.
* @return bool|string
*/
function rsssl_get_other_host() {
return rsssl_get_option( 'other_host_type', false );
}
}
/**
* Add some information to the javascript
* @param array $args
*
* @return array
*/
function rsssl_le_localize_script($args){
$hosting_dashboard = 'other';
if ( rsssl_is_cpanel() ) $hosting_dashboard = 'cpanel';
if ( rsssl_is_directadmin() ) $hosting_dashboard = 'directadmin';
if ( rsssl_is_plesk() ) $hosting_dashboard = 'plesk';
$args['hosting_dashboard'] = $hosting_dashboard;
return $args;
}
add_filter("rsssl_localize_script", 'rsssl_le_localize_script', 10, 3);
if ( !function_exists('rsssl_progress_add')) {
/**
* @param string $item
*/
function rsssl_progress_add( $item ) {
$progress = get_option( "rsssl_le_installation_progress", array() );
if ( ! in_array( $item, $progress ) ) {
$progress[] = $item;
update_option( "rsssl_le_installation_progress", $progress, false );
}
}
}
if ( !function_exists('rsssl_uses_known_dashboard')) {
/**
* Check if website uses any of the known dashboards.
*/
function rsssl_uses_known_dashboard( ) {
if ( rsssl_is_cpanel() || rsssl_is_plesk() || rsssl_is_directadmin() ) {
return true;
} else {
return false;
}
}
}
if ( !function_exists('rsssl_is_ready_for')) {
/**
* @param string $item
*/
function rsssl_is_ready_for( $item ) {
if ( !rsssl_do_local_lets_encrypt_generation() ) {
rsssl_progress_add('directories');
rsssl_progress_add('generation');
rsssl_progress_add('dns-verification');
}
if ( !rsssl_dns_verification_required() ) {
rsssl_progress_add('dns-verification');
}
if (empty(rsssl_get_not_completed_steps($item))){
return true;
} else{
return false;
}
}
}
function rsssl_get_not_completed_steps($item){
$sequence = array_column( rsssl_le_steps(), 'id');
//drop first
array_shift($sequence);
//drop all statuses after $item. We only need to know if all previous ones have been completed
$index = array_search($item, $sequence);
$sequence = array_slice($sequence, 0, $index, true);
$not_completed = array();
$finished = get_option("rsssl_le_installation_progress", array());
foreach ($sequence as $status ) {
if (!in_array($status, $finished)) {
$not_completed[] = $status;
}
}
return $not_completed;
}
if ( !function_exists('rsssl_progress_remove')) {
/**
* @param string $item
*/
function rsssl_progress_remove( $item ) {
$progress = get_option( "rsssl_le_installation_progress", array() );
if ( in_array( $item, $progress ) ) {
$index = array_search( $item, $progress );
unset( $progress[ $index ] );
update_option( "rsssl_le_installation_progress", $progress, false );
}
}
}
if ( !function_exists('rsssl_do_local_lets_encrypt_generation')) {
/**
* Check if the setup requires local certificate generation
* @return bool
*/
function rsssl_do_local_lets_encrypt_generation() {
$not_local_cert_hosts = RSSSL_LE()->hosts->not_local_certificate_hosts;
$current_host = rsssl_get_other_host();
if ( in_array( $current_host, $not_local_cert_hosts ) ) {
return false;
}
return true;
}
}
if ( !function_exists('rsssl_get_manual_instructions_text')) {
/**
* Manual installation instructions
*
* @param string $url
*
* @return string
*/
function rsssl_get_manual_instructions_text( $url ) {
$default_url = 'https://really-simple-ssl.com/install-ssl-certificate';
$dashboard_activation_required = rsssl_activation_required();
$activated_by_default = rsssl_activated_by_default();
$paid_only = rsssl_paid_only();
$button_activate = '<br><a href="' . $default_url . '" target="_blank" class="button button-primary">' . __( "Instructions", "really-simple-ssl" ) . '</a>&nbsp;&nbsp;';
$button_complete = '<br><a href="' . $default_url . '" target="_blank" class="button button-primary">' . __( "Instructions", "really-simple-ssl" ) . '</a>&nbsp;&nbsp;';
if ( $url === $default_url ) {
$complete_manually = sprintf( __( "Please complete manually in your hosting dashboard.", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
$activate_manually = sprintf( __( "Please activate it manually on your hosting dashboard.", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
} else {
$complete_manually = sprintf( __( "Please complete %smanually%s", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
$activate_manually = sprintf( __( "Please activate it on your dashboard %smanually%s", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
$button_activate .= '<a href="' . $url . '" target="_blank" class="button button-primary">' . __( "Go to activation", "really-simple-ssl" ) . '</a>';
$button_complete .= '<a href="' . $url . '" target="_blank" class="button button-primary">' . __( "Go to installation", "really-simple-ssl" ) . '</a>';
}
if ( $activated_by_default ) {
$msg
= sprintf( __( "According to our information, your hosting provider supplies your account with an SSL certificate by default. Please contact your %shosting support%s if this is not the case.",
"really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' ) . '&nbsp' .
__( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" );
} else if ( $dashboard_activation_required ) {
$msg = __( "You already have free SSL on your hosting environment.", "really-simple-ssl" ) . '&nbsp' .
$activate_manually . ' ' .
__( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" )
. $button_activate;
} else if ( $paid_only ) {
$msg
= sprintf( __( "According to our information, your hosting provider does not allow any kind of SSL installation, other then their own paid certificate. For an alternative hosting provider with SSL, see this %sarticle%s.",
"really-simple-ssl" ), '<a target="_blank" href="https://really-simple-ssl.com/hosting-providers-with-free-ssl">', '</a>' );
} else {
$msg = __( "Your hosting environment does not allow automatic SSL installation.", "really-simple-ssl" ) . ' ' .
$complete_manually . ' ' .
sprintf( __( "You can follow these %sinstructions%s.", "really-simple-ssl" ), '<a target="_blank" href="' . $default_url . '">', '</a>' ) . '&nbsp' .
__( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" )
. $button_complete;
}
return $msg;
}
}
register_activation_hook( __FILE__, 'rsssl_set_activation_time_stamp' );
if ( ! function_exists( 'rsssl_set_activation_time_stamp' ) ) {
function rsssl_set_activation_time_stamp( $networkwide ) {
update_option( 'rsssl_activation_time', time(), false );
}
}
if ( ! function_exists( 'rsssl_array_filter_multidimensional' ) ) {
function rsssl_array_filter_multidimensional(
$array, $filter_key, $filter_value
) {
$new = array_filter( $array,
function ( $var ) use ( $filter_value, $filter_key ) {
return isset( $var[ $filter_key ] ) ? ( $var[ $filter_key ]
== $filter_value )
: false;
} );
return $new;
}
}
if ( !function_exists('rsssl_is_subdomain') ) {
/**
* Check if we're on a subdomain.
* If this is a www domain, we return false
*/
function rsssl_is_subdomain(){
$domain = rsssl_get_domain();
if ( strpos($domain, 'www.') !== false ) return false;
$root = rsssl_get_root_domain($domain);
if ($root === $domain ) {
return false;
} else {
return true;
}
}
}
if ( !function_exists('rsssl_get_root_domain') ) {
/**
* Get root domain of a domain
*/
function rsssl_get_root_domain($domain){
$sub = strtolower(trim($domain));
$count = substr_count($sub, '.');
if($count === 2){
if(strlen(explode('.', $sub)[1]) > 3) $sub = explode('.', $sub, 2)[1];
} else if($count > 2){
$sub = rsssl_get_root_domain(explode('.', $sub, 2)[1]);
}
return $sub;
}
}
if ( ! function_exists( 'rsssl_get_domain' ) ) {
/**
* Get current domain
*
* @return string
*/
function rsssl_get_domain() {
//Get current domain
$domain = site_url();
//Parse to strip off any /subfolder/
$parse = parse_url($domain);
$domain = $parse['host'];
$domain = str_replace(array('http://', 'https://' ), '', $domain);
return $domain;
}
}
function rsssl_insert_after_key($array, $key, $items){
$keys = array_keys($array);
$key = array_search($key, $keys);
$array = array_slice($array, 0, $key, true) +
$items +
array_slice($array, 3, count($array)-3, true);
return $array;
}
if ( !function_exists('rsssl_wildcard_certificate_required') ) {
/**
* Check if the site requires a wildcard
*
* @return bool
*/
function rsssl_wildcard_certificate_required() {
//if DNS verification, create wildcard.
if ( rsssl_get_option('verification_type') === 'dns' ) {
return true;
}
if ( ! is_multisite() ) {
return false;
} else {
if ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
return true;
} else {
return false;
}
}
}
}
if ( !function_exists('rsssl_can_install_shell_addon') ) {
/**
* check if this environment has shell capability
*
* @return bool
*/
function rsssl_can_install_shell_addon(){
//if not cpanel
if ( !rsssl_is_cpanel() ) {
return false;
}
//if already installed
if (defined('rsssl_shell_path')){
return false;
}
if ( function_exists('shell_exec') || function_exists('system') || function_exists('passthru') || function_exists('exec') ) {
return true;
} else {
return false;
}
}
}
if ( !function_exists('rsssl_generated_by_rsssl')) {
/**
* If a bundle generation is completed, this value is set to true.
*
* @return bool
*/
function rsssl_generated_by_rsssl() {
return get_option( 'rsssl_le_certificate_generated_by_rsssl' );
}
}
/**
* Checks if a CAA DNS record is preventing the use of Let's Encrypt for the current site.
*
* @return bool Returns true if a CAA DNS record exists and does not allow Let's Encrypt, false otherwise.
*/
if ( ! function_exists( 'rsssl_caa_record_prevents_le' ) ) {
function rsssl_caa_record_prevents_le(): bool {
// Get DNS CAA records for site_url()
$caa_records = dns_get_record( parse_url( site_url(), PHP_URL_HOST ), DNS_CAA );
// If no CAA records found, return false
if ( empty( $caa_records ) ) {
return false;
}
// Check if the CAA record contains letsencrypt.org
$caa_contains_le = false;
foreach ( $caa_records as $caa_record ) {
if ( strpos( $caa_record['value'], 'letsencrypt.org' ) !== false ) {
$caa_contains_le = true;
break;
}
}
// If the CAA record is set, but does not contain letsencrypt.org, return true;
if ( ! $caa_contains_le ) {
return true;
}
// CAA record contains Let's Encrypt, generation allowed
return false;
}
}

View File

@@ -0,0 +1 @@
<?php // You don't belong here. ?>

View File

@@ -0,0 +1,255 @@
<?php
/**
* @package CloudWays
* @author Rogier Lankhorst
* @copyright Copyright (C) 2021, Rogier Lankhorst
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3
* @link https://really-simple-ssl.com
* @since Class available since Release 5.0.0
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
class rsssl_Cloudways {
private $email;
private $api_key;
public $ssl_installation_url;
/**
* Initiates the cloudways class.
*
* @param string $email
* @param string $api_key
*/
public function __construct( ) {
$this->email = rsssl_get_option('cloudways_user_email');
$this->api_key = RSSSL_LE()->letsencrypt_handler->decode( rsssl_get_option('cloudways_api_key') );
$this->ssl_installation_url = "";
}
/**
*
* @param string $method GET|POST|PUT|DELETE
* @param string $url relative URL for the call
* @param string $accessToken Access token generated using OAuth Call
* @param array $post Optional post data for the call
*
* @return RSSSL_RESPONSE
*/
private function callCloudwaysAPI( $method, $url, $accessToken, $post = [] ) {
$baseURL = 'https://api.cloudways.com/api/v1/';
try {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
curl_setopt( $ch, CURLOPT_URL, $baseURL . $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
if ( $accessToken ) {
curl_setopt( $ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $accessToken ] );
}
//ssl_domains[]=fungibleownership.com&ssl_domains[]=www.fungibleownership.com
$encoded = '';
if ( count( $post ) ) {
foreach ( $post as $name => $value ) {
if ( is_array( $value) ) {
foreach ( $value as $sub_value ) {
$encoded .= $name.'[]='.urlencode( $sub_value) . '&';
}
} else {
$encoded .= urlencode( $name ) . '=' . urlencode( $value ) . '&';
}
}
$encoded = substr( $encoded, 0, strlen( $encoded ) - 1 );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $encoded );
curl_setopt( $ch, CURLOPT_POST, 1 );
}
$output = curl_exec( $ch );
$httpcode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
if ($output && isset($output->error_description)) {
return new RSSSL_RESPONSE( 'error', 'stop', $output->error_description, false );
} else if ($httpcode != '200' && $output && isset($output->message) ){
return new RSSSL_RESPONSE( 'error', 'stop', $output->message );
} else if ( $httpcode != '200' ) {
$message = $httpcode . ' output: ' . substr( $output, 0, 10000 );
return new RSSSL_RESPONSE( 'error', 'stop', $message );
}
curl_close( $ch );
return new RSSSL_RESPONSE( 'success', 'continue', '', json_decode( $output ) );
} catch(Exception $e) {
return new RSSSL_RESPONSE( 'error', 'stop', $e->getMessage() );
}
}
/**
* Get an access token
* @return RSSSL_RESPONSE
*/
private function getAccessToken() {
$accessToken = get_transient('rsssl_cw_t');
if (!$accessToken) {
$response = $this->callCloudwaysAPI( 'POST', '/oauth/access_token', null, [ 'email' => $this->email, 'api_key' => $this->api_key ] );
if ($response->status === 'success' ) {
$accessToken = $response->output->access_token;
set_transient('rsssl_cw_t', $accessToken, 1800);
} else {
return new RSSSL_RESPONSE( 'error', 'stop', $response->message );
}
}
return new RSSSL_RESPONSE( 'success', 'continue','', $accessToken );
}
/**
* @param array $domains
*
* @return RSSSL_RESPONSE
*/
public function installSSL($domains){
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop',$response->message);
}
$accessToken = $response->output;
$response = $this->getServerInfo();
if ($response->status === 'success' ) {
$server_id = get_transient('rsssl_cw_server_id' );
$app_id = get_transient('rsssl_cw_app_id');
$args = [
'server_id' => $server_id,
'app_id' => $app_id,
'ssl_email' => $this->email,
'wild_card' => RSSSL_LE()->letsencrypt_handler->is_wildcard(),
'ssl_domains' => $domains,
];
$response = $this->callCloudWaysAPI( 'POST', 'security/lets_encrypt_install', $accessToken, $args );
}
return $response;
}
/**
*
* @return RSSSL_RESPONSE
*/
public function enableAutoRenew(){
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop', __("Failed retrieving access token","really-simple-ssl"));
}
$accessToken = $response->output;
$response = $this->getServerInfo();
if ($response->status === 'success' ) {
$app_id = get_transient('rsssl_cw_app_id');
$server_id = get_transient('rsssl_cw_server_id' );
$response = $this->callCloudWaysAPI( 'POST', 'security/lets_encrypt_auto', $accessToken,
[
'server_id' => $server_id,
'app_id' => $app_id,
'auto' => true,
]
);
}
if ( $response->status === 'success' ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully installed Let's Encrypt","really-simple-ssl");
} elseif ($response->status === 'error') {
//in some cases, the process is already started, which also signifies success.
if ( strpos($response->message, 'An operation is already in progress for this server')) {
$status = 'success';
$action = 'continue';
$message = __("Successfully installed Let's Encrypt","really-simple-ssl");
} else {
$status = $response->status;
$action = $response->action;
$message = $response->message;
}
} else {
$status = $response->status;
$action = $response->action;
$message = __("Error enabling auto renew for Let's Encrypt","really-simple-ssl");
}
return new RSSSL_RESPONSE( $status, $action, $message );
}
/**
* Get the server id and app id
*
* @return RSSSL_RESPONSE
*/
public function getServerInfo(){
if ( get_transient('rsssl_cw_app_id') && get_transient('rsssl_cw_server_id' ) ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully retrieved server id and app id","really-simple-ssl");
return new RSSSL_RESPONSE( $status, $action, $message );
}
$response = $this->getAccessToken();
if ( $response->status !== 'success' ) {
return new RSSSL_RESPONSE('error','stop', $response->message);
}
$accessToken = $response->output;
$response = $this->callCloudwaysAPI('GET', '/server', $accessToken );
$success = false;
if ($response->status === 'success') {
$serverList = $response->output;
$servers = $serverList->servers;
foreach ($servers as $server ){
$apps = $server->apps;
foreach ($apps as $app ){
$app_domain = $app->cname;
$this_site_domain = str_replace(array('https://', 'http://', 'www.'), '',site_url());
if (strpos($app_domain, $this_site_domain) !== false ) {
$success = true;
set_transient('rsssl_cw_app_id', $app->id, WEEK_IN_SECONDS);
set_transient('rsssl_cw_server_id', $server->id, WEEK_IN_SECONDS);
break 2;
}
}
}
}
if ( $success ) {
$status = 'success';
$action = 'continue';
$message = __("Successfully retrieved server id and app id","really-simple-ssl");
} else {
$status = 'error';
$action = 'stop';
if ( isset($serverList->error_description) ) {
$message = $serverList->error_description;
} else {
$message = __("Could not retrieve server list","really-simple-ssl");
}
}
return new RSSSL_RESPONSE( $status, $action, $message );
}
}

View File

@@ -0,0 +1,62 @@
<?php defined( 'ABSPATH' ) or die();
function rsssl_cloudways_server_data(){
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$cloudways = new rsssl_Cloudways();
return $cloudways->getServerInfo();
}
function rsssl_cloudways_install_ssl(){
if (rsssl_is_ready_for('installation')) {
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$domains = RSSSL_LE()->letsencrypt_handler->get_subjects();
$cloudways = new rsssl_Cloudways();
$response = $cloudways->installSSL($domains);
if ($response->status === 'success') {
update_option('rsssl_le_certificate_installed_by_rsssl', 'cloudways', false);
}
return $response;
} else {
$status = 'error';
$action = 'stop';
$message = __("The system is not ready for the installation yet. Please run the wizard again.", "really-simple-ssl");
return new RSSSL_RESPONSE($status, $action, $message);
}
}
function rsssl_cloudways_auto_renew(){
require_once( rsssl_le_path . 'integrations/cloudways/cloudways.php' );
$cloudways = new rsssl_Cloudways();
return $cloudways->enableAutoRenew();
}
function rsssl_cloudways_add_condition_actions($fields){
$index = array_search('installation',array_column($fields,'id'));
$fields[$index]['actions'] = array(
array(
'description' => __("Retrieving Cloudways server data...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_server_data',
'attempts' => 5,
'status' => 'inactive',
),
array(
'description' => __("Installing SSL certificate...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_install_ssl',
'attempts' => 5,
'status' => 'inactive',
),
array(
'description' => __("Enabling auto renew...", "really-simple-ssl"),
'action'=> 'rsssl_cloudways_auto_renew',
'attempts' => 5,
'status' => 'inactive',
),
);
//drop store credentials field
$creds_index = array_search('store_credentials',array_column($fields,'id'));
unset($fields[$creds_index]);
return $fields;
}
add_filter( 'rsssl_fields', 'rsssl_cloudways_add_condition_actions' );

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