Initial commit: Atomaste website

This commit is contained in:
2025-12-10 12:17:30 -05:00
commit 0b9e5d1605
19260 changed files with 5206382 additions and 0 deletions

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,75 @@
/**
*
* 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/file-change-detection.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/xml-rpc.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,114 @@
.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);
}
}
.number_full input[type=number] {
width: 100% !important;
position: relative;
}

View File

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

View File

@@ -0,0 +1,249 @@
/* 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;
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-disabled {
min-height:320px;//add min height on disabled so the settings is visible behind the locked div.
}
&.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 {
flex-grow: 100;
width: 100%;
box-sizing: border-box;
@include rsssl-inline-block-padding;
&:empty {
display: none;
}
}
&-footer {
display: flex;
flex-wrap: wrap;
align-items: center;
align-self: flex-end;
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;
.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;
min-width: 80px;
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,71 @@
.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;
}
.rsssl-progress-footer-link {
a {
color: inherit;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
}

View File

@@ -0,0 +1,135 @@
.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);
//}
}
&.button-primary {
// We disable all hover effects for the primary button as wel as active and focus
// This is to ensure that the primary button is always the same color
// and does not change on hover, focus or active
&:hover, &:focus, &:active {
box-shadow: none;
}
}
&.button-secondary {
// We disable all hover effects for the secondary button as wel as active and focus
// This is to ensure that the secondary button is always the same color
// and does not change on hover, focus or active
&:hover, &:focus, &:active {
box-shadow: none;
}
}
}
}
.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 {
overflow: visible;
}
.rsssl-action-buttons__button {
//add some spacing between the buttons
}
/* 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,431 @@
.rsssl-404_blocking, .rsssl-user_agents,.rsssl-content_security_policy_source_directives,
.rsssl-firewall_block_list_listing, .rsssl-vulnerabilities-measures-overview, .rsssl-two_fa_users,
.rsssl-firewall_list_listing, .rsssl-vulnerabilities_overview, .rsssl-permissions_policy, .rsssl-firewall_white_list_listing,
.rsssl-firewall_logs_content, .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-content_security_policy, .rsssl-hardening-xml {
.rsssl-field-wrap {
//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-search-bar {
float: right;
padding: 0;
}
.rsssl-search-bar__inner {
display: flex;
align-items: center;
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 {
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;
align-items: center;
Justify-content: space-between;
width: 100%;
padding: 1em 2em;
background: var(--rsp-blue-faded);
}
.rdt_TableRow .rdt_TableCell:last-child {
min-width: 20px;
float: right;
}
.rdt_TableRow .rdt_TableCell:last-child button,
.rdt_TableRow .rdt_TableCell:last-child span {
min-width: 20px;
float: right;
}
.rdt_TableCol, .rdt_TableCell, .rdt_TableCol_Sortable {
//all text to the left
flex-direction: row;
}
#cell-2-force_update > div > select {
max-width: 100%;
}
#cell-2-quarantine > div > select {
max-width: 100%;
}
.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-permissions_policy, .rsssl-field-wrap {
.rdt_TableHeadRow {
.rdt_TableCol:last-child {
flex-grow: 0;
min-width: initial;
justify-content: flex-end;
}
}
}
.rdt_TableRow {
.rdt_TableCell:last-child {
flex-grow: 0;
min-width: initial;
}
}
.rsssl-csp-revoked > div:nth-child(-n+3) {
opacity: 0.3;
}
.rsssl-content_security_policy, .rsssl-xml_rpc {
.rsssl-field-wrap > div > div {
overflow-x: inherit;
overflow-y: inherit;
}
}
.rsssl-mixed-content-datatable {
& > div > div {
display: flex;
}
}
.rsssl-vulnerabilities_measures {
.rdt_TableRow .rdt_TableCell:nth-child(3) {
max-width: 50%;
}
}
.rsssl-vulnerabilities_measures, .rsssl-404_blocking, .rsssl-user_agents, .rsssl-firewall_logs, .rsssl-permissions_policy, .rsssl-two_fa_users,
.rsssl-vulnerabilities-measures-overview, .rsssl-content_security_policy_source_directives,
.rsssl-firewall_white_list_listing, .rsssl-firewall_block_list_listing, .rsssl-firewall_list_listing,
.rsssl-vulnerabilities_overview, .rsssl-limit_login_attempts_country, .rsssl-limit_login_attempts_users,
.rsssl-firewall_event_log_viewer, .rsssl-firewall_logs_content, .rsssl-limit_login_attempts_event_log,
.rsssl-mixed-content-scan, .rsssl-limit_login_attempts_ip_address, .rsssl-content_security_policy, .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);
}
}
}
/* Section for EdgeCases and other specific styling */
/* EdgeCase: EventLog */
.rsssl-content_security_policy,
.rsssl-permissions_policy,
.rsssl-firewall_list_listing,
.rsssl-user_agents,
.rsssl-404_blocking,
.rsssl-firewall_white_list_listing,
.rsssl-firewall_block_list_listing,
.rsssl-hardening-xml,
.rsssl-vulnerabilities_overview,
.rsssl-content_security_policy_source_directives,
.rsssl-vulnerabilities-measures-overview,
.rsssl-limit_login_attempts_ip_address,
.rsssl-limit_login_attempts_users,
.rsssl-limit_login_attempts_country,
.rsssl-two_fa_users,
.rsssl-firewall_logs,
.rsssl-firewall_logs_content,
.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_TableHeadRow {
border: none;
}
.rdt_Pagination {
border: none;
}
.rdt_TableBody {
.rdt_TableRow {
border: none;
.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;
}
}
}
}
}
.rsssl-limit_login_attempts_event_log, .rsssl-firewall_logs_content {
// making sure the last child of the tablehead is positioned to the left
.rdt_TableHeadRow {
.rdt_TableCol:last-child {
justify-content: flex-start;
}
}
}
.rsssl-vulnerabilities-measures-overview {
.allowRowEvents {
overflow: visible !important;
.wp-core-ui select {
max-width: 100%;
}
}
div:first-child {
white-space: initial !important;
}
.rdt_TableCell {
&:nth-child(2) {
select {
max-width: 100%;
}
}
}
}
///* EdgeCase: CountryTable */
//.rsssl-vulnerabilities_measures {
// .rdt_TableCell {
// &:nth-child(2) {
// select {
// max-width: 100%;
// }
// }
// }
//}
///* EdgeCase: hardening-xml */
//.rsssl-hardening-xml {
//
// .rdt_Table {
// height: 300px;
// align-items: initial;
//
// div:nth-child(2) {
// align-items: baseline;
// }
//
// }
//
// .rdt_TableHead {
// padding-bottom: 10px;
// }
//
// .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: 0 !important;
}
}
}
}
}
.rsssl-vulnerabilities-measures-overview {
.rdt_TableRow .rdt_TableCell:last-child {
overflow: hidden;
text-overflow: ellipsis;
width: 200px;
}
}
//For the shields
.rsssl-content_security_policy_source_directives:has(.rsssl-shield-overlay) {
min-height: 250px;
}

View File

@@ -0,0 +1,13 @@
.dKzMcW, .fcbkgN {
padding-right: 0 !important;
}
.rsssl-exclude-button {
margin-left: 40px !important;
}
@media (max-width: 1440px) {
.rsssl-exclude-button {
margin-left: 5px !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,36 @@
.rsssl-modal.rsssl-onboarding {
width: clamp(300px, 100ch, 100vw );
padding-top: var(--rsp-spacing-m);
line-height: 2.2;
min-height:295px;
.rsssl-logo {
height: 26px;
}
.rsssl-modal-content{
display:flex;
min-height:295px;
.rsssl-onboarding-placeholder {
flex-grow:1
}
&-step {
display:flex;
flex-direction: column;
width:100%;
}
.rsssl-processing {
opacity:0.5;
}
ul{
li {
.rsssl-icon{
margin-top: 7px;
}
.components-button.is-link {
padding:5px 0;
}
}
}
}
}

View File

@@ -0,0 +1,89 @@
.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-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,91 @@
@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;
}
animation: shine-lines $animation-duration infinite linear;
@include background-gradient;
@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,75 @@
.rsssl {
.rsssl-locked {
position: relative;
z-index: 0;
&.rsssl-locked-premium {
.rsssl-locked-overlay {
bottom: var(--rsp-spacing-s);
flex-direction: column;
z-index: 0;
}
}
.rsssl-locked-overlay {
display: flex;
bottom: 0;
text-align: left;
margin-bottom: 20px;
padding: 0;
z-index: 0;
&.rsssl-premium {
bottom: 0;
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,260 @@
.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-icon.rsssl-icon-loading {
padding:3px;
}
}
.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,48 @@
a.rsssl-skip-link {
display: flex;
justify-content: center;
margin: 15px 0 20px;
}
.rsssl-two_fa_users div[data-column-id="5"].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;
}
.rsssl-two_fa_general,
.rsssl-two_fa_email,
.rsssl-two_fa_totp,
.rsssl-two_fa_users {
.MuiPopper-root, .MuiPaper-root {
max-height: 30px;
z-index: 15;
div {
font-family: inherit !important;
}
ul {
max-height: initial;
}
}
}
.rsssl-add-button__inner .button {
display: flex;
align-items: center;
}
.rsssl-add-button__inner .button .icon {
margin-left: 8px; /* Adjust the spacing as needed */
}

View File

@@ -0,0 +1,178 @@
.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: 20;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(255, 255, 255, 0.8);
border-radius: var(--rsp-border-radius);
.rsssl-shield-overlay {
position: absolute;
top: 50%; /* Center vertically */
left: 50%; /* Center horizontally */
transform: translate(-50%, -50%); /* Offset for centering */
display: flex;
align-items: center;
justify-content: center;
height: calc(100px + 2 * var(--rsp-spacing-s)); /* Adjust shield height dynamically */
width: calc(200px + 2 * var(--rsp-spacing-s)); /* Ensure consistent width for a square shield */
z-index: 19; /* Place it below the overlay */
}
.rsssl-locked:has(.rsssl-shield-overlay) {
/* Apply dynamic styles when .rsssl-shield-overlay is present */
min-height: calc(100px + 4 * var(--rsp-spacing-s)); /* Adjust to fit the shield and extra spacing */
display: flex;
align-items: center; /* Vertically center contents */
justify-content: center; /* Horizontally center contents */
position: relative; /* Context for absolutely positioned children */
padding: var(--rsp-spacing-s); /* Add padding to avoid cutting off elements */
}
.rsssl-locked-overlay {
z-index: 20; /* Ensure this stays on top */
position: absolute;
display: flex;
align-items: center;
gap: var(--rsp-spacing-s);
background-color: var(--rsp-white);
margin: var(--rsp-spacing-s);
border-radius: var(--rsp-border-radius-s);
box-shadow: var(--rsp-box-shadow);
bottom: 0;
width: calc(100% - (2 * var(--rsp-spacing-s)));
@include rsssl-block-padding;
.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: 20; //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);
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;
@include rsssl-block-padding();
box-shadow: var(--rsp-box-shadow);
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,213 @@
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;
}
.rsssl-block-highlight {
border: 0;
-o-animation: pulse 2s infinite;
animation: pulse 2s infinite;}
@-webkit-keyframes pulse {
0% {
-webkit-box-shadow: 0 0 0 0 var(--rsp-green);
}
70% {
-webkit-box-shadow: 0 0 0 10px var(--rsp-green-faded);
}
100% {
-webkit-box-shadow: 0 0 0 0 var(--rsp-green-faded);;
}
}
@keyframes pulse {
0% {
-moz-box-shadow: 0 0 0 0 var(--rsp-green);
box-shadow: 0 0 0 0 var(--rsp-green);
}
70% {
-moz-box-shadow: 0 0 0 10px var(--rsp-green-faded);
box-shadow: 0 0 0 10px var(--rsp-green-faded);
}
100% {
-moz-box-shadow: 0 0 0 0 var(--rsp-green-faded);
box-shadow: 0 0 0 0 var(--rsp-green-faded);
}
}
@-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;
}
.rsssl-ip-verified {
position: absolute;
bottom: 8px;
right: 6px;
}
//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,125 @@
.rsssl-lets-encrypt-tests {
margin: var(--rsp-spacing-xs) var(--rsp-spacing-xl);
.rsssl-features {
ul {
display: flex;
list-style-type: none;
padding: 0;
margin: 0;
.rsssl-checkbox-items {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-right: var(--rsp-spacing-l);
}
}
}
.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,142 @@
.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-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,31 @@
.rsssl-vulnerability-action {
a.button {
margin-left:10px;
}
}
.rsssl-processing {
opacity:0.5;
}
.rsssl-vulnerabilities_measures-overview {
.allowRowEvents {
.wp-core-ui select {
max-width: 100%;
}
}
.rdt_TableCell {
&:nth-child(2) {
select {
max-width: 100%;
}
}
}
}
.rsssl-vulnerabilities_measures {
.rsssl-locked-overlay {
input[type=checkbox] {
margin-top: 0;
}
}
}

View File

@@ -0,0 +1,7 @@
.rsssl div[class^=rsssl-wizard-] .rsssl-hardening-xml {
.rsssl-locked .rsssl-shield-overlay {
align-items: center;
display: flex;
justify-content: center;
}
}

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,158 @@
// 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

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
<?php login_header(); ?>
<form class="login-form">
<h3><?php echo esc_html__('Two-Factor Authentication', 'really-simple-ssl'); ?></h3>
<br>
<p>
<?php echo esc_html($message) ?>
</p>
</form>
<?php login_footer();

View File

@@ -0,0 +1,113 @@
<?php
login_header();
if ( ! empty( $error_msg ) ) {
echo '<div id="login_error" class="notice notice-error"><strong>Error: </strong>' . esc_html( $error_msg ) . '<br /></div>';
} else {
\RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor::maybe_show_last_login_failure_notice( $user );
}
?>
<form name="rsssl_validate_2fa_form" id="loginform"
action="<?php echo esc_url( \RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor::login_url( array( 'action' => 'validate_2fa' ), 'login_post' ) ); ?>"
method="post" autocomplete="off">
<input type="hidden" name="provider" id="provider" value="<?php echo esc_attr( $provider_class ); ?>"/>
<input type="hidden" name="rsssl-wp-auth-id" id="rsssl-wp-auth-id"
value="<?php echo esc_attr( $user->ID ); ?>"/>
<input type="hidden" name="rsssl-wp-auth-nonce" id="rsssl-wp-auth-nonce"
value="<?php echo esc_attr( $login_nonce ); ?>"/>
<?php if ( $interim_login ) { ?>
<input type="hidden" name="interim-login" value="1"/>
<?php } else { ?>
<input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>"/>
<?php } ?>
<input type="hidden" name="rememberme" id="rememberme" value="<?php echo esc_attr( $rememberme ); ?>"/>
<?php $provider->authentication_page( $user ); ?>
</form>
<?php
if ( get_class($provider) === 'RSSSL\Pro\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Totp') {
?>
<div class="backup-methods-wrap">
<!-- <p class="backup-methods">-->
<!-- <a>-->
<!-- --><?php
// echo esc_html__('Or, enter your backup code.', 'really-simple-ssl');
// ?>
<!-- </a>-->
<!-- </p>-->
</div>
<?php
}
?>
<style>
/* @todo: migrate to an external stylesheet. */
.backup-methods-wrap {
margin-top: 16px;
padding: 0 24px;
}
.backup-methods-wrap a {
color: #999;
text-decoration: none;
}
ul.backup-methods {
display: none;
padding-left: 1.5em;
}
/* Prevent Jetpack from hiding our controls, see https://github.com/Automattic/jetpack/issues/3747 */
.jetpack-sso-form-display #loginform > p,
.jetpack-sso-form-display #loginform > div {
display: block;
}
#login form p.two-factor-prompt {
margin-bottom: 1em;
}
.input.rsssl-authcode {
letter-spacing: .3em;
}
.input.rsssl-authcode::placeholder {
opacity: 0.5;
}
</style>
<script>
(function () {
// Enforce numeric-only input for numeric inputmode elements.
const form = document.querySelector('#loginform'),
inputEl = document.querySelector('input.rsssl-authcode[inputmode="numeric"]'),
expectedLength = inputEl?.dataset.digits || 0;
if (inputEl) {
let spaceInserted = false;
inputEl.addEventListener(
'input',
function () {
let value = this.value.replace(/[^0-9 ]/g, '').trimStart();
if (!spaceInserted && expectedLength && value.length === Math.floor(expectedLength / 2)) {
value += ' ';
spaceInserted = true;
} else if (spaceInserted && !this.value) {
spaceInserted = false;
}
this.value = value;
// Auto-submit if it's the expected length.
if (expectedLength && value.replace(/ /g, '').length == expectedLength) {
if (undefined !== form.requestSubmit) {
form.requestSubmit();
form.submit.disabled = "disabled";
}
}
}
);
}
})();
</script>

View File

@@ -0,0 +1,161 @@
<?php
// first we validate the data variables
use RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Email;
use RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Totp;
/**
* @param $variable
* @param $default
* @return void
*/
function rsssl_check_and_set(&$variable, $default = null)
{
if (!isset($variable)) {
$variable = $default;
}
}
// Use the function for all your variables
$variables_to_check = array(
'available_providers',
'selected_provider',
'rememberme',
'interim_login',
'nonce',
'login_nonce',
'action',
'redirect_to',
'url',
'minified_js',
'minified_css',
'interim_login',
'backup_providers',
'provider',
'primary_provider',
'$skip_two_fa_url',
'is_today'
);
foreach ($variables_to_check as $var) {
rsssl_check_and_set($$var);
}
login_header();
// We create the onboarding form.
?>
<form id="two_fa_onboarding_form" class="login-form" method="post">
<h3><?php echo esc_html__('Two-Factor Authentication', 'really-simple-ssl'); ?></h3>
<p>
<?php
if ($is_forced) {
echo esc_html__(
'This site requires you to secure your account with a second authentication method.',
'really-simple-ssl'
);
} else {
echo sprintf(esc_html__(
'You can protect your account with a second authentication layer. Please choose one of the following methods, or click %s if you dont want to use Two-Factor Authentication.',
'really-simple-ssl'
), esc_html__('Don\'t ask again', 'really-simple-ssl'));
}
?>
</p>
<?php
if ($is_forced && $grace_period) {
?>
<br/>
<p>
<?php
if (!$is_today) {
echo sprintf(esc_html__(
'Please make sure to configure a method, access to your account will be denied if no method is configured within the next %s days.',
'really-simple-ssl'
), $grace_period);
} else {
echo esc_html__('Please make sure to configure a method, access to your account will be denied if no method is configured today.', 'really-simple-ssl');
}
?>
</p>
<?php
}
?>
<div id="rsssl_step_one_onboarding" class="rsssl_step_one_onboarding">
<?php
// We loop through the available providers and create a radio button for each but the first one if it is TOTP is checked
foreach ($available_providers as $provider) {
$checked = get_class($provider) === $primary_provider;
$provider::get_selection_option($user, $checked);
}
?>
</div>
<div id="rsssl_step_two_onboarding" class="rsssl_step_two_onboarding">
<p>
<?php
try {
Rsssl_Two_Factor_Totp::display_onboarding_step_totp($user);
} catch (Exception $e) {
// We just continue to the redirected page
wp_redirect($redirect_to);
}
?>
</p>
</div>
<div id="rsssl_step_three_onboarding" class="rsssl_step_three_onboarding">
<p class="two-factor-prompt"><?php echo esc_html__('A verification code has been sent to the email address associated with your account.', 'really-simple-ssl'); ?></p>
<p>
<label for="rsssl-authcode"><?php echo esc_html__('Verification Code:', 'really-simple-ssl'); ?></label>
<input type="text" inputmode="numeric" name="rsssl-two-factor-email-code" id="rsssl-authcode"
class="input rsssl-authcode" value="" size="20" pattern="[0-9 ]*" placeholder="1234 5678"
data-digits="8"/>
</p>
<p class="rsssl-two-factor-email-resend">
<button class="button"
id="<?php echo esc_attr(Rsssl_Two_Factor_Email::RSSSL_INPUT_NAME_RESEND_CODE); ?>"
name="<?php echo esc_attr(Rsssl_Two_Factor_Email::RSSSL_INPUT_NAME_RESEND_CODE); ?>"><?php esc_attr_e('Resend Code', 'really-simple-ssl'); ?></button>
</p>
</div>
<p class="skip_container">
<?php
if (!$is_forced) {
?>
<a href="#" id="do_not_ask_again">
<?php echo esc_html__('Don\'t ask again', 'really-simple-ssl'); ?>
</a>
<a href="#" id="skip_onboarding">
<?php echo esc_html__('Skip', 'really-simple-ssl'); ?>
</a>
<?php
} else {
// We check if there is a grace period.
if ($grace_period) {
?>
<a href="#" id="skip_onboarding">
<?php
if ($is_today) {
echo esc_html__('Skip (Only today remaining)', 'really-simple-ssl');
} else {
echo sprintf(
esc_html__('Skip (%1$d %2$s remaining)', 'really-simple-ssl'),
$grace_period,
$grace_period > 1 ? esc_html__('days', 'really-simple-ssl') : esc_html__('day', 'really-simple-ssl')
);
}
?>
</a>
<?php
} else {
?>
<span></span>
<?php
}
}
?>
<input type="submit" id="rsssl_continue_onboarding" name="onboarding_submit"
class="button button-primary button-large"
value="<?php echo esc_html__('Continue', 'really-simple-ssl'); ?>"/>
</p>
</form>
<?php
login_footer();

View File

@@ -0,0 +1,133 @@
<?php
/**
* This file contains the profile settings for the Two-Factor Authentication.
* It is used to display the Two-Factor Authentication settings on the user profile page.
* It also contains the logic to save the Two-Factor Authentication settings.
*
* @package really-simple-ssl-pro
* @since 4.0.0
*
*/
require_once rsssl_path . 'security/wordpress/two-fa/class-rsssl-two-factor-settings.php';
use RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Email;
use RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Settings;
?>
<br>
<p>
<h2><?php esc_html__('Two-Factor Authentication', 'really-simple-ssl'); ?></h2>
<p><?php esc_html__('Two-Factor Authentication adds an extra layer of security to your account. You can enable it here.', 'really-simple-ssl'); ?></p>
<?php if ($forced && !$one_enabled) : ?>
<p class="notice notice-warning">
<?php esc_html_e('Two-Factor Authentication is mandatory for your account, so you need to make a selection.', 'really-simple-ssl'); ?>
</p>
<?php endif; ?>
<table class="form-table rsssl-table-two-fa">
<!-- Two-Factor Authentication Selection -->
<tr>
<th scope="row">
<label for="two-factor-authentication"><?php esc_html_e('Two-Factor Authentication', 'really-simple-ssl'); ?></label>
</th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php esc_html_e('Two-Factor Authentication', 'really-simple-ssl'); ?></span>
</legend>
<label for="two-factor-authentication">
<input type="hidden" name="two-factor-authentication" value="<?php echo $forced ?>" />
<input type="checkbox" name="two-factor-authentication" id="two-factor-authentication"
value="1" <?php checked($one_enabled || $forced);
disabled($forced) ?> />
<?php esc_html_e('Enable Two-Factor Authentication', 'really-simple-ssl'); ?>
</label>
</fieldset>
</td>
</tr>
<!-- Two-Factor Authentication Selection -->
<?php if (!empty($backup_codes) && $one_enabled) : ?>
<tr>
<th scope="row">
<label for="two-factor-backup-codes"><?php esc_html_e('Backup Codes', 'really-simple-ssl'); ?></label>
</th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php esc_html_e('Backup Codes', 'really-simple-ssl'); ?></span>
</legend>
<!-- Displaying the download for the backup codes if Two-Factor Authentication is enabled -->
<a href="#"
id="download_codes"><?php esc_html_e('Download Backup Codes', 'really-simple-ssl'); ?></a>
<span class="rsssl-backup-codes warning"><?php esc_html_e('Codes only available for 5 minutes') ?></span>
</fieldset>
</td>
</tr>
<?php endif; ?>
<!-- Two-Factor Authentication Method Selection -->
<tr id="selection_two_fa">
<th scope="row">
<label for="two-factor-method"><?php echo esc_html__('Selected provider', 'really-simple-ssl'); ?></label>
</th>
<td>
<fieldset>
<legend class="screen-reader-text">
<span><?php esc_html_e('Preferred Method', 'really-simple-ssl'); ?></span>
</legend>
<?php foreach (!$one_enabled? $available_providers:$providers as $provider) : ?>
<label for="two-factor-method-<?php echo esc_attr($provider); ?>">
<input type="radio" name="preferred_method" class="preferred_method_selection" id="preferred_method_<?= $provider::METHOD ?>"
value="<?= esc_attr($provider::METHOD) ?>" <?php checked(strtolower($provider::METHOD) === strtolower(Rsssl_Two_Factor_Settings::get_login_action( $user->ID ))); ?> />
<?= esc_html($provider::NAME) ?>
<br/>
<?php endforeach; ?>
</fieldset>
</td>
</tr>
<tr class="totp-config">
<td>
<div id="qr-code-container">
<p id="two-factor-qr-code">
<a href="<?= esc_url($totp_url) ?>">
Loading...
<img src="<?= esc_url(admin_url('images/spinner.gif')) ?>" alt=""/>
</a>
</p>
<p style="margin-bottom: 10px;">
<i id="totp-key">
<?php
echo esc_html(__('Copy setup key', 'really-simple-ssl'));
?>
</i>
</p>
<label for="two-factor-totp-authcode">
<strong><?php esc_html_e('Authentication Code:', 'really-simple-ssl'); ?></strong>
<?php
/* translators: Example auth code. */
$placeholder = sprintf(__('eg. %s', 'really-simple-ssl'), '123 456');
?>
<input type="tel" name="two-factor-totp-authcode" id="two-factor-totp-authcode" class="input"
value=""
size="20" pattern="[0-9 ]*" placeholder="<?= esc_attr($placeholder) ?>"/>
</label>
<!-- TOTP hidden fields -->
<input type="hidden" name="two-factor-totp-key" id="two-factor-totp-key"
value="<?= esc_attr($key) ?>"/>
<input type="hidden" name="two-factor-totp-url" id="two-factor-totp-url"
value="<?= esc_attr($totp_url) ?>"/>
</div>
</td>
</tr>
<tr id="rsssl_verify_email" class="rsssl_verify_email">
<td colspan="2">
<label for="rsssl-two-factor-email-code"><?php esc_html_e('Verification Code:', 'really-simple-ssl'); ?></label>
<input type="text" inputmode="numeric" name="rsssl-two-factor-email-code" id="rsssl-two-factor-email-code"
class="input rsssl-authcode" value="" size="20" pattern="[0-9 ]*" placeholder="1234 5678"
data-digits="8"/>
<p class="two-factor-prompt"><i><?php esc_html_e('A verification code has been sent to the email address associated with your account to verify functionality.', 'really-simple-ssl'); ?> <a href="#" id="rsssl_resend_code_action"> <?php esc_attr_e('Resend Code', 'really-simple-ssl'); ?></a></i></p>
</td>
</tr>
</table>

View File

@@ -0,0 +1,24 @@
<?php
if (!isset($user) || !$user instanceof WP_User) {
// We throw an error here because the $user variable is required
throw new RuntimeException('The $user variable is required.');
}
//checking all other variables
if (!isset($badge_class, $enabled_text, $checked_attribute, $title, $description, $type, $forcible)) {
return; // Return early if variables are not set
}
?>
<p>
<label class="radio-label">
<strong><?php echo $title ?></strong>
<input type="radio" name="preferred_method" value="<?php echo $type ?>"
class="radio-input" <?php echo $checked_attribute; ?>/>
</label>
<br>
<?php
echo $description;
// Get the user's role.
$user_roles = $user->roles;
// If this is in the forced roles, we do not show the "disable" link.
?>
</p>

View File

@@ -0,0 +1,54 @@
<?php
// Ensure the $user variable is available
if (!isset($user) || !$user instanceof WP_User) {
// We throw an error here because the $user variable is required
throw new RuntimeException('The $user variable is required.');
}
if (isset($_GET['error']) && $_GET['error'] === 1) {
?>
<p class="error">
<?php echo esc_html__('Authentication code is incorrect.', 'really-simple-ssl'); ?>
</p>
<?php
}
?>
<br/>
<p>
<strong><?php echo esc_html__('Install Authentication app:', 'really-simple-ssl'); ?></strong><br/>
<?php
printf(
// Translators: %s is the hyperlink for "Download"
esc_html__('Use your authenticator app like Google Authenticator to scan the QR code below, then paste the provided Authentication code. %s', 'really-simple-ssl'),
'<a id="download_codes" href="#">' . esc_html__('Download Backup Codes', 'really-simple-ssl') . '</a>'
);
?>
</p>
<p id="two-factor-qr-code">
<a href="#">
Loading...
<img src="<?php echo esc_url(admin_url('images/spinner.gif')); ?>" alt=""/>
</a>
</p>
<p style="margin-bottom: 10px;">
<i id="totp-key">
<?php
echo esc_html__('Copy setup key', 'really-simple-ssl');
?>
</i>
</p>
<p>
<label for="two-factor-totp-authcode">
<strong><?php echo esc_html__('Authentication Code:', 'really-simple-ssl'); ?></strong>
<?php
/* translators: Example auth code. */
$placeholder = sprintf(esc_html__('eg. %s', 'really-simple-ssl'), '123 456');
?>
<input type="tel" name="two-factor-totp-authcode" id="two-factor-totp-authcode" class="input" value=""
size="20" pattern="[0-9 ]*" placeholder="<?php echo esc_attr($placeholder); ?>"/>
</label>
</p>
<input type="submit" class="button button-primary button-large totp-submit" name="two-factor-totp-submit"
id="two-factor-totp-submit"
value="<?php echo esc_html__('Submit', 'really-simple-ssl'); ?>"/>

View File

@@ -0,0 +1 @@
#two-factor-qr-code{display:flex;justify-content:left;align-items:center;width:100%;min-height:100%}#qr-code-container{margin-bottom:20px;position:relative;text-align:center}#two-factor-totp-authcode{width:100%}tr.rsssl_verify_email{display:none}.error{color:red;margin-top:-5px}span.rsssl-backup-codes{padding:5px;background:#fbebed;border-radius:8px;box-shadow:rgba(0,0,0,0.1) 0 4px 6px -1px}.input{margin-bottom:5px !important}#totp-key{cursor:pointer;display:flex;justify-content:center;align-items:center}table.rsssl-table-two-fa{padding-bottom:20px}.rsssl-methods-tag{padding:2px 5px;border:1px solid #000;color:#000;margin-left:5px;background:dimgrey}.rsssl-methods-tag.active{background:darkgreen;color:#fff}.radio-input{position:absolute;right:0;margin-left:10px;vertical-align:middle;top:5px}.radio-label{display:inline-block;vertical-align:middle;width:100%;position:relative;margin:20px 0}.badge{margin-left:10px;padding:2px 4px}.badge-default{background-color:#e5e5e5;color:black}.badge-enabled{background-color:#fbc43e;color:black}#two_fa_onboarding_form{margin-top:20px}#two_fa_onboarding_form div{transition:height .5s}#skip_onboarding{margin-right:20px}.skip_container{display:flex;justify-content:space-between;align-items:center;margin-top:10px}.skip_container a{text-decoration:none}.totp-submit{margin-top:10px}div.rsssl_step_one_onboarding{display:block}div.rsssl_step_two_onboarding{display:none}div.rsssl_step_three_onboarding{margin-top:10px;display:none}#two-factor-qr-code{display:flex;justify-content:center;align-items:center;min-width:205px;min-height:205px}.error{color:red;margin-top:-5px}.input{margin-bottom:5px !important}#totp-key{cursor:pointer;display:flex;justify-content:center;align-items:center}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,174 @@
#two-factor-qr-code {
display: flex;
/* Enables Flexbox */
justify-content: left;
/* Centers horizontally */
align-items: center;
/* Centers vertically */
width: 100%;
min-height: 100%;
}
#qr-code-container {
margin-bottom: 20px;
position: relative;
text-align: center;
}
#two-factor-totp-authcode {
width: 100%;
}
tr.rsssl_verify_email {
display: none;
}
.error {
color: red;
margin-top: -5px;
}
span.rsssl-backup-codes {
padding: 5px;
background: #fbebed;
border-radius: 8px;
box-shadow: rgba(0, 0, 0, 0.1) 0 4px 6px -1px;
}
.input {
margin-bottom: 5px !important;
}
#totp-key {
cursor: pointer;
display: flex;
/* Enables Flexbox */
justify-content: center;
/* Centers horizontally */
align-items: center;
/* Centers vertically */
}
table.rsssl-table-two-fa {
padding-bottom: 20px;
}
.rsssl-methods-tag {
padding: 2px 5px;
border: 1px solid #000;
color: #000;
margin-left: 5px;
background: dimgrey;
}
.rsssl-methods-tag.active {
background: darkgreen;
color: #fff;
}
/* Style radio inputs */
.radio-input {
position: absolute;
right: 0;
margin-left: 10px;
/* Adjust this value to your preferred spacing */
vertical-align: middle;
top: 5px;
}
/* Style radio labels */
.radio-label {
display: inline-block;
vertical-align: middle;
width: 100%;
position: relative;
margin: 20px 0;
}
.badge {
margin-left: 10px;
padding: 2px 4px;
}
.badge-default {
background-color: #e5e5e5;
color: black;
}
.badge-enabled {
background-color: #fbc43e;
color: black;
}
/**
* The following styles are for the onboarding form
*/
#two_fa_onboarding_form {
margin-top: 20px;
}
#two_fa_onboarding_form div {
transition: height 0.5s;
}
#skip_onboarding {
margin-right: 20px;
}
.skip_container {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
.skip_container a {
text-decoration: none;
}
.totp-submit {
margin-top: 10px;
}
div.rsssl_step_one_onboarding {
display: block;
}
div.rsssl_step_two_onboarding {
display: none;
}
div.rsssl_step_three_onboarding {
margin-top: 10px;
display: none;
}
#two-factor-qr-code {
display: flex;
/* Enables Flexbox */
justify-content: center;
/* Centers horizontally */
align-items: center;
/* Centers vertically */
min-width: 205px;
min-height: 205px;
}
.error {
color: red;
margin-top: -5px;
}
.input {
margin-bottom: 5px !important;
}
#totp-key {
cursor: pointer;
display: flex;
/* Enables Flexbox */
justify-content: center;
/* Centers horizontally */
align-items: center;
/* Centers vertically */
}

View File

@@ -0,0 +1,137 @@
<?php
defined( 'ABSPATH' ) or die( );
if ( ! class_exists( 'rsssl_cache' ) ) {
class rsssl_cache {
private static $_this;
public function __construct() {
if ( isset( self::$_this ) ) {
wp_die( 'you cannot create a second instance.' );
}
self::$_this = $this;
}
public 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,278 @@
<?php defined( 'ABSPATH' ) or die();
if ( ! class_exists( 'rsssl_certificate' ) ) {
class rsssl_certificate {
private static $_this;
public function __construct() {
if ( isset( self::$_this ) ) {
wp_die( 'you cannot create a second instance.' );
}
self::$_this = $this;
}
public static function this() {
return self::$_this;
}
/**
*
* @since 3.0
*
* Check if the certificate is valid
*
* @return bool
*
*/
public function is_valid(): bool {
$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
* @param $certinfo
* @param $domain
* @return bool
*
*/
public function is_domain_valid( $certinfo, $domain ): bool {
//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 ( false !== $pos_cn || false !== $pos_an ) {
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 $subject_alt_name ) {
$cert_domains[] = trim( str_replace( '*', '', $subject_alt_name ) );
}
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 && 'no-response' === $certinfo ) {
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;
$subject_alt_names = 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( $subject_alt_names ) ) {
foreach ( $subject_alt_names as $subject_alt_name ) {
if ( strpos( $subject_alt_name, '*' ) !== 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 ( 'no-response' === $certinfo ) {
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 ( 0 === $errno && $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 ( 'not-valid' === $certinfo ) {
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,92 @@
<?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;
public function __construct() {
if ( isset( self::$_this ) ) {
wp_die( 'you cannot create a second instance.' );
}
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 );
}
public 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, 'WordPress - Really Simple Security' );
exit;
}
}
}
}

View File

@@ -0,0 +1,178 @@
<?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 ( 'download' === $step ) {
$this->download_plugin();
}
if ( 'activate' === $step ) {
$this->activate_plugin();
}
}
/**
* Get slug to activate plugin with
* @return string
*/
public function get_activation_slug() {
$slugs = [
'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 = [
'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' );
delete_transient( $prefix . '_redirect_to_settings_page' );
}
/**
* Download the plugin
* @return bool
*/
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 );//phpcs:ignore
}
$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,613 @@
<?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_multisite_menu' ) );
/*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('plugins_loaded', array($this, 'maybe_redirect_old_settings_url'), 10);
if ( is_network_admin() ) {
add_action('network_admin_notices', array($this, 'show_notices'), 10);
}
//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;
}
}
/**
* 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';
}
/**
* 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>" : "";
$icon_svg = '<?xml version="1.0" encoding="UTF-8"?>
<svg id="rss-menu-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 -15 100 130" width="28" height="28">
<defs>
<style>.cls-1{fill:#fff;stroke-width:0px;}</style>
</defs>
<g fill="none" stroke-width="2">
<path class="cls-1" d="M72.92,26.6h-13v-9.4c0-7.6-6.1-13.7-13.7-13.7s-13.8,6.1-13.8,13.7v9.4h-13.1v-9.4C19.32,2.4,31.32,-9.6,46.12,-9.6s26.8,12,26.8,26.8v9.4h0Z"/>
<rect class="cls-1" x="10.02" y="84.6" width="72.3" height="5.6"/>
<path class="cls-1" d="M82.32,82H10.02V31.8c0-2.9,2.3-5.2,5.2-5.2h61.9c2.9,0,5.2,2.3,5.2,5.2V82h0ZM64.62,37.8c-2.2-2.2-5.9-2.2-8.2,0l-15.7,15.3l-4.9-4.9c-2.2-2.2-5.9-2.2-8.2,0l-1.9,1.9c-2.2,2.2-2.2,5.9,0,8.2l8.5,8.5c0.1,0.2,0.3,0.4,0.5,0.6l1.9,1.9l4.2,4l3.5-3.5c0.2-0.1,0.4-0.3,0.6-0.5l1.9-1.9c0.2-0.2,0.4-0.4,0.5-0.6l19.1-18.9c2.2-2.2,2.2-5.9,0-8.2l-1.8-1.9Z"/>
</g>
</svg>';
$icon_base64 = 'data:image/svg+xml;base64,' . base64_encode($icon_svg);
$page_hook_suffix = add_menu_page(
__( "Security", "really-simple-ssl" ),
__( "Security", "really-simple-ssl" ) . $update_count,
'manage_security',
'really-simple-security',
'rsssl_settings_page',
$icon_base64,
100 // This will place it near the bottom of the menu
);
add_action( "admin_print_scripts-{$page_hook_suffix}", 'rsssl_plugin_admin_scripts' );
// Update the page title to prevent issues with an empty title causing strip_tags deprecation warnings
add_action("load-{$page_hook_suffix}", 'rsssl_set_admin_page_title');
add_action('admin_head', 'rsssl_override_wordpress_svg_size');
}
/**
* 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');
rsssl_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
*
* @param string $domain
*
* @access public
*
* @return bool
* @since 2.2
*
*/
public function is_subfolder(string $domain): bool {
//remove slashes of the http(s)
$domain = preg_replace("/(http:\/\/|https:\/\/)/", "", $domain);
return strpos( $domain, "/" ) !== 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 = 'open' === $notice['status'] ? 'warning' : 'error';
$more_info = $notice['url'] ?? false;
$logo = $notice['logo'] ?? false;
$dismiss_id = isset( $notice['dismissible'] ) && $notice['dismissible'] ? $id : false;
$dashboard_button = isset( $notice['dashboard_button'] ) && $notice['dashboard_button'] ? $id : false;
echo RSSSL()->admin->notice_html( $class . ' ' . $id, $notice['msg'], $more_info, $logo, $dismiss_id, $dashboard_button );
}
}
}
/**
* 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,189 @@
<?php
defined( 'ABSPATH' ) or die( 'you do not have access to this page!' );
if ( ! class_exists( 'rsssl_server' ) ) {
class rsssl_server {
private static $_this;
private $sapi = false;
public function __construct() {
if ( isset( self::$_this ) ) {
wp_die( 'you cannot create a second instance.' );
}
self::$_this = $this;
}
public 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'] ) );
if ( strpos( $server_raw, 'apache' ) !== false ) {
return 'apache';
} elseif ( strpos( $server_raw, 'nginx' ) !== false ) {
return 'nginx';
} elseif ( strpos( $server_raw, 'litespeed' ) !== false ) {
return 'litespeed';
} elseif ( strpos( $server_raw, 'openresty' ) !== false ) {
return 'openresty';
} elseif ( strpos( $server_raw, 'microsoft-iis' ) !== false ) {
return 'microsoft-iis';
} else { //unsupported server
return false;
}
}
/**
* Get the Auto prepend configuration
*
* @return string
*/
public function auto_prepend_config(): string
{
$return = '';
if ( $this->isApacheModPHP() ){
$return = "apache-mod_php"; //Apache _ modphp
} else if ( $this->isApacheSuPHP() ) {
$return = "apache-suphp"; //Apache + SuPHP
} else if ( $this->isApache() && !$this->isApacheSuPHP() && ($this->isCGI() || $this->isFastCGI()) ) {
$return = "cgi"; //Apache + CGI/FastCGI
} else if ($this->isLiteSpeed()){
$return = "litespeed";
} else if ( $this->isNGINX() ) {
$return = "nginx";
} else if ( $this->isIIS() ) {
$return = "iis";
} else {
$return = "apache-mod_php";
}
update_option('rsssl_auto_prepend_config', $return, true);
return $return;
}
/**
* If Apache
* @return bool
*/
public function isApache():bool {
return $this->get_server() === 'apache';
}
/**
* If NGINX
* @return bool
*/
public function isNGINX():bool {
return $this->get_server() === 'nginx';
}
/**
* If Litespeed
* @return bool
*/
public function isLiteSpeed():bool {
return $this->get_server() === 'litespeed';
}
/**
* If IIS
* @return bool
*/
public function isIIS():bool {
return $this->get_server() === 'iis';
}
/**
* If ModPHP
* @return bool
*/
public function isApacheModPHP():bool {
return $this->isApache() && function_exists('apache_get_modules');
}
/**
* If SupPHP
* Not sure if this can be implemented at the PHP level.
* @return bool
*/
public function isApacheSuPHP():bool {
return $this->isApache() && $this->isCGI() &&
function_exists('posix_getuid') &&
getmyuid() === posix_getuid();
}
/**
* If CGI
* @return bool
*/
public function isCGI():bool {
return !$this->isFastCGI() && stripos($this->sapi(), 'cgi') !== false;
}
/**
* If FastCGI
* @return bool
*/
public function isFastCGI():bool {
return stripos($this->sapi(), 'fastcgi') !== false || stripos($this->sapi(), 'fpm-fcgi') !== false;
}
/**
* If Sapi
* @return bool|string
*/
private function sapi(){
if ( !$this->sapi ) {
$this->sapi = function_exists('php_sapi_name') ? php_sapi_name() : 'false';
}
if ( 'false' === $this->sapi ) {
return false;
}
return $this->sapi;
}
/**
* 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,380 @@
<?php defined( 'ABSPATH' ) or die();
if ( ! class_exists( 'rsssl_site_health' ) ) {
class rsssl_site_health {
private static $_this;
public function __construct() {
if ( isset( self::$_this ) ) {
wp_die( 'you cannot create a second instance.' );
}
add_filter( 'site_status_tests', array( $this, 'health_check' ), 1, 10 );
self::$_this = $this;
}
public 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 ( rsssl_maybe_disable_404_blocking() ) {
$tests['direct']['rsssl_404_test'] = array(
'test' => array( $this, 'site_health_404_display' ),
);
}
if ( rsssl_get_option( 'enable_vulnerability_scanner' ) ) {
$vulnerabilities = new rsssl_vulnerabilities();
$tests['direct']['rsssl_vulnerabilities'] = array(
'test' => [ $vulnerabilities, 'get_site_health_notice' ],
);
}
// Two-Factor Authentication (2FA) test
$tests['direct']['rsssl_2fa_test'] = array(
'label' => __( 'Two-Factor Authentication', 'really-simple-ssl' ),
'test' => array( $this, 'two_factor_auth_test' ),
);
// Limit Login Attempts (LLA) test
$tests['direct']['rsssl_lla_test'] = array(
'label' => __( 'Limit Login Attempts Protection', 'really-simple-ssl' ),
'test' => array( $this, 'limit_login_attempts_test' ),
);
// Firewall Protection test
$tests['direct']['rsssl_firewall_test'] = array(
'label' => __( 'Firewall Protection', 'really-simple-ssl' ),
'test' => array( $this, 'firewall_test' ),
);
}
return $tests;
}
/**
* Test for Two-Factor Authentication (2FA)
* @return array
*/
public function two_factor_auth_test() {
$status = 'recommended';
$description = __( 'We recommend to enable Two-Factor Authentication at least for administrators.', 'really-simple-ssl' );
// Check if RSSSL 2FA, WordFence, Solid Security, AIOS are installed and 2FA is enabled
if ( rsssl_get_option('login_protection_enabled') == '1' || is_plugin_active('wordfence/wordfence.php') || is_plugin_active('two-factor/two-factor.php') || is_plugin_active('all-in-one-wp-security-and-firewall/wp-security.php') || is_plugin_active('better-wp-security/better-wp-security.php') ) {
$status = 'good';
$description = __( 'Your site is protected by Two-Factor Authentication (2FA).', 'really-simple-ssl' );
}
return array(
'label' => __( 'Protect your user logins with Two-Factor Authentication (at least for Administrator accounts)', 'really-simple-ssl' ),
'status' => $status,
'badge' => array(
'label' => __( 'Security', 'really-simple-ssl' ),
'color' => 'blue',
),
'description' => sprintf( '<p>%s</p>', $description ),
'actions' => sprintf(
'<p><a href="%s" target="_blank">%s</a></p>',
esc_url( admin_url( 'admin.php?page=really-simple-security#settings/two-fa' ) ),
__( 'Read more', 'really-simple-ssl' )
),
'test' => 'rsssl_2fa_test',
);
}
/**
* Test for Limit Login Attempts (LLA)
* @return array
*/
public function limit_login_attempts_test() {
$status = 'recommended';
$description = __( 'Enable Limit Login Attempts to protect the login form against brute-force attacks.', 'really-simple-ssl' );
// Check if RSSSL LLA or Limit Login Attempts Reloaded is installed and active
if ( rsssl_get_option('enable_limited_login_attempts') == '1' || is_plugin_active('wordfence/wordfence.php') || is_plugin_active('limit-login-attempts-reloaded/limit-login-attempts-reloaded.php') || is_plugin_active('better-wp-security/better-wp-security.php') ) {
$status = 'good';
$description = __( 'Your site is protected by Limit Login Attempts.', 'really-simple-ssl' );
}
return array(
'label' => __( 'Protect your login form with Limit Login Attempts', 'really-simple-ssl' ),
'status' => $status,
'badge' => array(
'label' => __( 'Security', 'really-simple-ssl' ),
'color' => 'blue',
),
'description' => sprintf( '<p>%s</p>', $description ),
'actions' => sprintf(
'<p><a href="%s" target="_blank">%s</a></p>',
esc_url( admin_url( 'admin.php?page=really-simple-security#settings/limit_login_attempts' ) ),
__( 'Read more', 'really-simple-ssl' )
),
'test' => 'rsssl_lla_test',
);
}
/**
* Test for Firewall Protection
* @return array
*/
public function firewall_test() {
$status = 'recommended';
$description = __( 'Secure your site with the performant Firewall.', 'really-simple-ssl' );
// Check if WordFence, AIOS, or Solid Security is installed
if ( rsssl_get_option('enable_firewall') || is_plugin_active('wordfence/wordfence.php') || is_plugin_active('all-in-one-wp-security-and-firewall/wp-security.php') || is_plugin_active('better-wp-security/better-wp-security.php') ) {
$status = 'good';
$description = __( 'Your site is protected by a firewall.', 'really-simple-ssl' );
}
return array(
'label' => __( 'Secure your site with a Firewall', 'really-simple-ssl' ),
'status' => $status,
'badge' => array(
'label' => __( 'Security', 'really-simple-ssl' ),
'color' => 'blue',
),
'description' => sprintf( '<p>%s</p>', $description ),
'actions' => sprintf(
'<p><a href="%s" target="_blank">%s</a></p>',
esc_url( admin_url( 'admin.php?page=really-simple-security#settings/firewall' ) ),
__( 'Read more', 'really-simple-ssl' )
),
'test' => 'rsssl_firewall_test',
);
}
/**
* 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' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'status' => 'recommended',
'badge' => array(
'label' => __( 'Security' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'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 noreferrer">%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( rsssl_admin_url([], '#settings/hardening') ),
__( 'Remove from public location with Really Simple Security', 'really-simple-ssl' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )// phpcs:ignore WordPress.WP.I18n.MissingArgDomain
),
'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' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'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 noreferrer">%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( rsssl_link('security/debug-display-enabled') ),
__( 'Read more about security concerns with debug display enabled', 'really-simple-ssl' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )// phpcs:ignore WordPress.WP.I18n.MissingArgDomain
),
'test' => 'rsssl_debug_display',
);
return $result;
}
/**
* Check for 404 errors.
*
*/
public function site_health_404_display() {
$result = array(
'label' => __( '404 errors detected on your homepage', 'really-simple-ssl' ),
'status' => 'critical',
'badge' => array(
'label' => __( 'Security' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( '404 errors detected on your homepage. This means that the page requests images, scripts or other resources that are no longer available. It can interfere with your Firewall as well.', 'really-simple-ssl' )
),
'actions' => sprintf(
'<p><a href="%s" target="_blank" rel="noopener noreferrer">%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( rsssl_link('404-not-found-errors') ),
__( 'Read more', 'really-simple-ssl' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )// phpcs:ignore WordPress.WP.I18n.MissingArgDomain
),
'test' => 'rsssl_404_test',
);
return $result;
}
/**
* Test to check if the recommended security headers are present
* @return array
*/
public function headers_test() {
$result = array(
'label' => __( 'Essential security headers installed', 'really-simple-ssl' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Security' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'The essential 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 essential security headers are installed', 'really-simple-ssl' );
$result['description'] = sprintf( '<p>%s</p>', __( 'Your website does not send all essential security headers.', 'really-simple-ssl' ) . $style . $list );
$result['actions'] = sprintf(
'<p><a href="%s" target="_blank" rel="noopener noreferrer">%s</a></p>',
rsssl_link('site-health-recommended-security-headers/'),
__( 'Read more', 'really-simple-ssl' )
);
}
return $result;
}
/**
* Some basic SSL health checks
* @return array
*/
public function ssl_tests() {
$url = rsssl_admin_url();
$result = array(
'label' => __( '301 SSL redirect enabled', 'really-simple-ssl' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Security' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
'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'] = 'recommended';
$result['label'] = __( 'SSL is not enabled.', 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__(
'Really Simple Security 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'] = 'recommended';
$result['label'] = __( 'No SSL detected', 'really-simple-ssl' );
$result['description'] = sprintf(
'<p>%s</p>',
__( 'Really Simple Security 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' )
);
} elseif ( 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,83 @@
<?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' );
//We add the devtools command to the WP-CLI
if (file_exists(rsssl_path . 'pro/assets/tools/cli/class-rsssl-stub-generator.php')) {
require_once rsssl_path . 'pro/assets/tools/cli/class-rsssl-stub-generator.php';
}

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, false, false );
} 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, false, false );
}
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,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 Security is already deactivated!</h1>";
exit;
}
$step = 1;
echo "<h1>Force deactivation of Really Simple Security</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,376 @@
<?php
defined( 'ABSPATH' ) or die();
/**
* Only functions also required on front-end here
*/
/**
* Get a Really Simple Security option by name
*
* @param string $name The name of the option to retrieve.
* @param mixed $default_value The default value to return if the option does not exist.
*
* @return mixed
*/
if (!function_exists('rsssl_get_option')) {
function rsssl_get_option( string $name, $default_value = 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 ] ) &&
( 'ssl_enabled' === $name || 'redirect' === $name || 'mixed_content_fixer' === $name || 'dismiss_all_notices' === $name )
) {
$options = rsssl_get_legacy_option( $options, $name );
}
$value = $options[ $name ] ?? false;
if ( false === $value && false !== $default_value ) {
$value = $default_value;
}
if ( 1 === $value ) {
$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
*/
if (!function_exists('rsssl_is_networkwide_active')) {
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
*/
if (!function_exists('rsssl_get_legacy_option')) {
function rsssl_get_legacy_option( $options, string $name ): array {
$old_options = is_multisite() ? get_site_option( 'rlrsssl_network_options' ) : get_option( 'rlrsssl_options' );
$options = [];
if ( $old_options ) {
if ( 'ssl_enabled' === $name && isset( $old_options['ssl_enabled'] ) ) {
$options['ssl_enabled'] = $old_options['ssl_enabled'];
} elseif ( 'dismiss_all_notices' === $name && isset( $old_options['dismiss_all_notices'] ) ) {
$options['dismiss_all_notices'] = $old_options['dismiss_all_notices'];
} elseif ( 'dismiss_all_notices' === $name && isset( $old_options['dismiss_all_notices'] ) ) {
$options['dismiss_all_notices'] = $old_options['dismiss_all_notices'];
} elseif ( 'mixed_content_fixer' === $name && isset( $old_options['autoreplace_insecure_links'] ) ) {
$options['mixed_content_fixer'] = $old_options['autoreplace_insecure_links'];
} elseif ( 'redirect' === $name ) {
if ( isset( $old_options['htaccess_redirect'] ) && $old_options['htaccess_redirect'] ) {
$options['redirect'] = 'htaccess';
} elseif ( isset( $old_options['wp_redirect'] ) && $old_options['wp_redirect'] ) {
$options['redirect'] = 'wp_redirect';
}
}
}
return $options;
}
}
if (!function_exists('rsssl_check_if_email_essential_feature')) {
function rsssl_check_if_email_essential_feature() {
$essential_features = array(
'limit_login_attempts' => rsssl_get_option( 'enable_limited_login_attempts' ) == 1,//phpcs:ignore
'login_protection_enabled' => rsssl_get_option( 'login_protection_enabled' ) == 1,//phpcs:ignore
);
// 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;
}
}
/**
* Retrieves the path to a template file.
*
* @param string $template The name of the template to retrieve.
* @param string $path (Optional) The path to look for the template file. If not specified, the default path will be used.
*
* @return string The full path to the template file.
* @throws \RuntimeException Throws a runtime exception if the template file cannot be found.
*/
if (!function_exists('rsssl_get_template')) {
function rsssl_get_template( string $template, string $path = '' ): string {
// Define the path in the theme where templates can be overridden.
$theme_template_path = get_stylesheet_directory() . '/really-simple-ssl-templates/' . $template;
// Check if the theme has an override for the template.
if ( file_exists( $theme_template_path ) ) {
return $theme_template_path;
}
// If $path is not set, use the default path
if ( $path === '' ) {
$path = rsssl_path . 'templates/'; // Remember this only works in free version, for pro we need to add the $path parameter/argument
} else {
// Ensure the path ends with a slash
$path = trailingslashit( $path );
}
// Full path to the template file
$full_path = $path . $template;
// Check if the template exists in the specified path.
if ( ! file_exists( $full_path ) ) {
throw new \RuntimeException( 'Template not found: ' . $full_path );
}
return $full_path;
}
}
/**
* Loads a template file and includes it.
*
* @param string $template The name of the template to load.
* @param array $vars (Optional) An associative array of variables to make available in the template scope.
* @param string $path (Optional) The path to look for the template file. If not specified, the default path will be used.
*
* @return void
* @throws Exception Throws an exception if the template file cannot be found.
*/
if (!function_exists('rsssl_load_template')) {
function rsssl_load_template( string $template, array $vars = array(), string $path = '' ) {
// Extract variables to be available in the template scope.
if ( is_array( $vars ) ) {
extract( $vars );
}
// Get the template file, checking for theme overrides.
$template_file = rsssl_get_template( $template, $path );
// Include the template file.
include $template_file;
}
}
/**
* Determines the path to WordPress configuration file (wp-config.php)
*
* This function attempts to locate the wp-config.php file in the following order:
* 1. Checks for a filtered path via 'rsssl_wpconfig_path' filter
* 2. Looks in the WordPress installation root directory (ABSPATH)
* 3. Looks in the parent directory of the WordPress installation
*
* @return string The full path to wp-config.php if found, empty string otherwise
*
* @filter rsssl_wpconfig_path Allows modification of the wp-config.php path
*
* @example
* // Get wp-config.php path
* $config_path = rsssl_wpconfig_path();
*
* // Filter example
* add_filter('rsssl_wpconfig_path', function($path) {
* return '/custom/path/to/wp-config.php';
* });
*/
if ( ! function_exists( 'rsssl_wpconfig_path' ) ) {
function rsssl_wpconfig_path(): string {
// Allow the wp-config.php path to be overridden via a filter.
$filtered_path = apply_filters( 'rsssl_wpconfig_path', '' );
// If a filtered path is provided and valid, use it.
if ( ! empty( $filtered_path ) && file_exists( $filtered_path ) ) {
return $filtered_path;
}
// Default behavior to locate wp-config.php
$location_of_wp_config = ABSPATH;
if ( ! file_exists( ABSPATH . 'wp-config.php' ) && file_exists( dirname( ABSPATH ) . '/wp-config.php' ) ) {
$location_of_wp_config = dirname( ABSPATH );
}
$location_of_wp_config = trailingslashit( $location_of_wp_config );
$wpconfig_path = $location_of_wp_config . 'wp-config.php';
// Check if the file exists and return the path if valid.
if ( file_exists( $wpconfig_path ) ) {
return $wpconfig_path;
}
// Return an empty string if no valid wp-config.php path is found.
return '';
}
}
/**
* @return void
*
* Set encryption keys
*/
if ( ! function_exists('rsssl_set_encryption_key')) {
function rsssl_set_encryption_key(): void {
// Return if key has been set
if ( get_site_option( 'rsssl_encryption_keys_set' ) ) {
return;
}
$wp_config_path = rsssl_wpconfig_path();
// Check if we already have a key defined
if ( defined( 'RSSSL_KEY' ) ) {
return;
}
$key = get_site_option( 'rsssl_main_key' );
$new_generated = false;
// If we don't have a key, generate one
if ( ! $key ) {
$new_generated = true;
$key = wp_generate_password( 64, false );
}
if ( is_writable( $wp_config_path ) ) {
// Add the key to the wp-config file
$rule = "//Begin Really Simple Security key\n";
$rule .= "define('RSSSL_KEY', '" . $key . "');\n";
$rule .= "//END Really Simple Security key\n";
$insert_after = '<?php';
$contents = file_get_contents( $wp_config_path );
$pos = strpos( $contents, $insert_after );
if ( false !== $pos && strpos( $contents, 'RSSSL_KEY' ) === false ) {
$contents = substr_replace( $contents, $rule, $pos + 1 + strlen( $insert_after ), 0 );
file_put_contents( $wp_config_path, $contents );
}
// If the wp-config was just set to writable, we can delete the key from the database now.
delete_site_option( 'rsssl_main_key' );
} elseif ( $new_generated ) {
// If we can't write to the wp-config file, store the key in the database
// When wp-config is set to writable, auto upgrade to constant
update_site_option( 'rsssl_main_key', $key, false );
}
update_site_option( 'rsssl_encryption_keys_set', true );
}
rsssl_set_encryption_key();
}
if ( ! function_exists( 'rsssl_deactivate_alternate' ) ) {
/**
* Deactivate the alternate version if active. This function is included in
* both the pro and free plugin and should be used to deactivate the
* alternate version upon activation.
* @param string $target The target plugin to deactivate
*/
function rsssl_deactivate_alternate(string $target = 'free') {
// we use this to ensure the base function doesn't load, as the active
// plugins function does not update yet. See RSSSL() in main plugin file
define( "RSSSL_DEACTIVATING_ALTERNATE", true );
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
$alternate_plugin_path = 'really-simple-ssl-pro/really-simple-ssl-pro.php';
if ($target === 'free') {
$alternate_plugin_path = 'really-simple-ssl/rlrsssl-really-simple-ssl.php';
}
if ( is_plugin_active( $alternate_plugin_path ) ) {
$delete_data_on_uninstall_was_enabled = false;
# Temporarily disable delete_data_on_uninstall option in rsssl_options
if ( is_multisite() && rsssl_is_networkwide_active() ) {
$options = get_site_option( 'rsssl_options', [] );
} else {
$options = get_option( 'rsssl_options', [] );
}
if ( isset( $options['delete_data_on_uninstall'] ) && $options['delete_data_on_uninstall'] ) {
$options['delete_data_on_uninstall'] = false;
$delete_data_on_uninstall_was_enabled = true;
}
if ( is_multisite() && rsssl_is_networkwide_active() ) {
update_site_option( 'rsssl_options', $options );
} else {
update_option( 'rsssl_options', $options );
}
update_option('rsssl_free_deactivated', true);
if ( function_exists('deactivate_plugins' ) ) {
deactivate_plugins( $alternate_plugin_path );
}
// Ensure the function exists to prevent fatal errors in case of
// direct access. Don't delete if debug enabled, for dev purposes.
// Also, only delete the free plugin.
$debug_enabled = defined('WP_DEBUG') && WP_DEBUG;
if ($target === 'free' && !$debug_enabled && function_exists( 'delete_plugins' ) && function_exists('request_filesystem_credentials' ) ) {
delete_plugins( array( $alternate_plugin_path ) );
}
# Now re-enable delete_data_on_uninstall if it was enabled
if ( $delete_data_on_uninstall_was_enabled ) {
$options['delete_data_on_uninstall'] = true;
if ( is_multisite() && rsssl_is_networkwide_active() ) {
update_site_option( 'rsssl_options', $options );
} else {
update_option( 'rsssl_options', $options );
}
}
$ssl_enabled = rsssl_get_option('ssl_enabled');
if ( $ssl_enabled ) {
rsssl_update_option('ssl_enabled', true);
}
// Delete free translations files from /wp-content/languages/plugins where files contain really-simple-ssl
if ($target === 'free' && defined( 'WP_CONTENT_DIR' ) ) {
$languages_plugins_dir = WP_CONTENT_DIR . '/languages/plugins';
if ( is_dir( $languages_plugins_dir ) && is_writable( $languages_plugins_dir ) ) {
$files = scandir( $languages_plugins_dir );
foreach ( $files as $file ) {
if ( is_file( $languages_plugins_dir . '/' . $file ) &&
strpos( $file, 'really-simple-ssl' ) === 0 ) {
@unlink( $languages_plugins_dir . '/' . $file );
}
}
}
}
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,281 @@
<?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 );
//register this manual change, so we don't force change it back.
update_option('rsssl_manually_changed_verification_type', true, false);
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(true);
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');
delete_option('rsssl_manually_changed_verification_type');
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

View File

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

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