Skip to content

Commit

Permalink
Merge pull request #7 from linchpin/feature/add-click-to-view
Browse files Browse the repository at this point in the history
Added the ability to click to view a secret instead of viewing it directly
  • Loading branch information
aaronware authored Nov 4, 2019
2 parents 93f0ac0 + f966a43 commit 5444bc5
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "linchpin-psst",
"title": "Pretty Secure Secret Transmission",
"version": "1.0.0",
"version": "1.0.5",
"description": "A pretty secure and simple plugin to transmit messages secretly.",
"homepage": "https://linchpin.com",
"main": "gulp.babel.js",
Expand Down
6 changes: 3 additions & 3 deletions psst.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?php
/*
* Plugin Name: psst (Pretty Secure Secret Transmission)
* Description: As simple plugin to send a relatively secure message to an individuals.
* Description: As simple plugin to send a relatively secure message to an individuals. Use at own risk
* Plugin URI: https://github.com/linchpin/psst
* Version: 1.0.3
* Version: 1.0.5
* License: GPL-2.0+
* Author URI: https://linchpin.com
* Text Domain: psst
Expand Down Expand Up @@ -38,7 +38,7 @@
}

if ( ! defined( 'PSST_VERSION' ) ) {
define( 'PSST_VERSION', '1.0.3' );
define( 'PSST_VERSION', '1.0.5' );
}

/**
Expand Down
178 changes: 156 additions & 22 deletions src/Controller/Secret.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Secret {
public function register_actions() {
add_action( 'init', [ $this, 'register_custom_post_type' ] );
add_action( 'init', [ $this, 'add_rewrite_rules' ] );
add_action( 'cmb2_admin_init', array( $this, 'register_fields' ) );
add_action( 'cmb2_admin_init', [ $this, 'register_fields' ] );

// Handle Secret Creation
add_action( 'admin_post_psst_create_secret', [ $this, 'create_secret' ] );
Expand All @@ -28,19 +28,24 @@ public function register_actions() {
add_action( 'admin_post_psst_delete_secret', [ $this, 'delete_secret' ] );
add_action( 'admin_post_nopriv_psst_delete_secret', [ $this, 'delete_secret' ] );

add_action( 'wp', [ $this, 'track_viewed_secret' ] );

add_filter( 'query_vars', [ $this, 'query_vars' ] );
add_filter( 'post_password_required', [ $this, 'skip_password_on_confirm' ], 10, 2 );
// Handle Secret View
add_action( 'admin_post_psst_view_secret', [ $this, 'view_secret' ] );
add_action( 'admin_post_nopriv_psst_view_secret', [ $this, 'view_secret' ] );

add_action( 'the_post', [ $this, 'the_post' ] );
add_filter( 'the_content', [ $this, 'confirmation_content' ], 2, 1 );
add_action( 'loop_end', [ $this, 'loop_end' ] );
add_action( 'loop_end', [ $this, 'track_viewed_secret' ] );

add_action( 'pre_get_posts', [ $this, 'display_confirmation' ] );
add_action( 'wp_enqueue_scripts', [ $this, 'wp_enqueue_scripts' ], 11 );
add_action( 'after_setup_theme', [ $this, 'add_editor_styles' ] );

// Filters
add_filter( 'query_vars', [ $this, 'query_vars' ] );
add_filter( 'post_password_required', [ $this, 'skip_password_on_confirm' ], 10, 2 );
add_filter( 'the_content', [ $this, 'display_secret_content' ], 2, 1 );

// Shortcodes
add_shortcode( 'secret_form', [ $this, 'secret_form' ] );
}

Expand Down Expand Up @@ -95,28 +100,113 @@ public function wp_enqueue_scripts() {
}

/**
* When showing the confirmation page. Do not show the message, show the confirmation message for the message.
* Check to see if we are viewing a secret creation confirmation page.
*
* @since 1.0.4
* @return bool
*/
private function is_confirmation() {

global $post;

if ( 'secret' === $post->post_type &&
is_single() &&
in_the_loop() &&
is_main_query() &&
get_query_var( 'confirm_secret_key' )
) {
return true;
}

return false;
}

/**
* Check to see if we are viewing the "click to view" page.
*
* Usage: This is used to determine if we are viewing the click to view page
* vs the actual secret.
*
* @since 1.0.4
* @return bool
*/
private function is_click_to_view() {
global $post;

if ( 'secret' === $post->post_type &&
is_single() &&
in_the_loop() &&
is_main_query() &&
get_query_var( 'confirm_secret_click' )
) {
return true;
}

return false;
}

/**
* Check to see if we clicked the view secret button
*
* @since 1.0.4
* @return bool
*/
private function can_view_secret() {
global $post;

if ( 'secret' === $post->post_type &&
is_single() &&
in_the_loop() &&
is_main_query() &&
'true' === get_query_var( 'confirm_secret_view' )
) {
return true;
}

return false;
}

/**
* Determine when to show the confirmation page, view secret confirmation or the secret itself.
*
* @since 1.0.0
*/
public function confirmation_content( $content ) {
public function display_secret_content( $content ) {

global $post;

if ( 'secret' === $post->post_type && is_single() && in_the_loop() && is_main_query() && get_query_var( 'confirm_secret_key' ) ) {
// If it's not a secret then don't filter anything
if ( 'secret' !== $post->post_type ) {
return $content;
}

if ( $this->is_confirmation() ) {

wp_enqueue_script( 'clipboard', PSST_PLUGIN_URL . 'js/clipboard.min.js', [], PSST_VERSION, true );

$confirmation = new View();
$timestamp = get_post_meta( $post->ID, '_psst_secret_expiration', true );
$date = date_i18n(
get_option( 'date_format' ),
$timestamp
);
$time = date_i18n(
get_option( 'time_format' ),
$timestamp
);

$datetime = sprintf( '%1$s @ %2$s', $date, $time );
$datetime = apply_filters( 'psst_date_time_format', $datetime );

$confirmation->assign( 'secret_expiration_date', $datetime );
$confirmation->assign( 'secret_confirm_key', get_post_meta( $post->ID, '_psst_secret_confirm_key', true ) );

return $confirmation->get_text_view( 'secret-confirmation' );
}

// Unencrypt our business
if ( 'secret' === $post->post_type && is_single() && in_the_loop() && is_main_query() ) {

$refresh_warning = '';
$refresh_warning = '';

if ( $this->can_view_secret() ) {
if ( ! post_password_required() ) {
$key = Key::loadFromAsciiSafeString( PSST_CRYPTO_KEY );
$content = Crypto::decrypt( $content, $key );
Expand All @@ -125,10 +215,17 @@ public function confirmation_content( $content ) {
$refresh_warning = $warning->get_text_view( 'secret-refresh-warning' );
$refresh_warning = apply_filters( 'psst_refresh_warning', $refresh_warning );
}

$content = $content . $refresh_warning;
} else {
// Show the OK button
if ( ! post_password_required() ) {
$secret_view = new View();
$content = $secret_view->get_text_view( 'secret' );
$content = apply_filters( 'psst_secret_view', $content );
}
}

$content = $content . $refresh_warning;

return $content;
}

Expand All @@ -141,7 +238,10 @@ public function display_confirmation( $query ) {

$secret_confirm_key = get_query_var( 'confirm_secret_key' );

if ( ! is_admin() && ( $query->is_main_query() && 'true' === get_query_var( 'confirm_secret' ) && 'secret' === $query->query_vars['post_type'] ) ) {
if ( ! is_admin() &&
( $query->is_main_query() &&
'true' === get_query_var( 'confirm_secret' ) &&
'secret' === $query->query_vars['post_type'] ) ) {

if ( ! empty( $secret_confirm_key ) ) {

Expand Down Expand Up @@ -190,44 +290,61 @@ public function skip_password_on_confirm( $protect, $post ) {
public function query_vars( $qvars ) {
$qvars[] = 'confirm_secret';
$qvars[] = 'confirm_secret_key';
$qvars[] = 'confirm_secret_click';
$qvars[] = 'confirm_secret_view';
return $qvars;
}

/**
* Track that a secret has been viewed so it can be deleted.
* Be sure to exclude if you are viewing the password protected form.
*
* @since 1.0.0
*/
public function track_viewed_secret() {

global $post;
global $post, $wp_query;

if ( is_admin() ) {
return;
}

if ( empty( $post ) ) {
return;
}

// Don't track if our post isn't a secret
if ( $post && 'secret' !== $post->post_type ) {
return;
}

// 'Slackbot-LinkExpanding 1.0'
// Don't track if we're on the confirm click view
if ( 'true' === get_query_var( 'confirm_secret_click' ) ) {
return;
}

// If the post isn't protected, delete it after it's been viewed.
// Also make sure that we aren't viewing the confirmation page.
if ( ! post_password_required() && 'true' !== get_query_var( 'confirm_secret' ) && ! is_404() ) {
wp_delete_post( $post->ID, true );
if ( ! post_password_required() &&
'true' === get_query_var( 'confirm_secret_view' ) &&
is_single() &&
! is_404()
) {
wp_delete_post( $post->ID, true );
}
}

/**
* Create custom rewrite rule for secrets.
*
* @since 1.0.0
*/
public function add_rewrite_rules() {
add_rewrite_tag( '%secret_id%', '([0-9A-Za-z]+)' );
add_rewrite_tag( '%confirm_secret_key%', '([0-9A-Za-z]+)' );
add_rewrite_rule( 'secret/confirm/(.*)/?', 'index.php?&post_type=secret&confirm_secret=true&confirm_secret_key=$matches[1]', 'top' );
add_rewrite_rule( 'secret/(.*)/?', 'index.php?&secret=$matches[1]', 'top' );
add_rewrite_rule( 'secret/view/(.*)/?', 'index.php?&secret=$matches[1]&confirm_secret_view=true', 'top' );
add_rewrite_rule( 'secret/(.*)/?', 'index.php?&secret=$matches[1]&confirm_secret_click=true', 'top' );
add_rewrite_rule( 'secret/removed/?', 'index.php?&removed_secret=true', 'top' );
}

Expand Down Expand Up @@ -341,7 +458,7 @@ public function create_secret() {
$expire_date = new \DateTime();
date_add( $expire_date, new \DateInterval( "PT{$expiration}M" ) );

update_post_meta( $new_secret_id, '_secret_expiration', $expire_date->getTimestamp() );
update_post_meta( $new_secret_id, '_psst_secret_expiration', $expire_date->getTimestamp() );
}

$confirm_url = site_url( 'secret/confirm/' . $generated_confirm_key );
Expand All @@ -351,6 +468,23 @@ public function create_secret() {
}
}

/**
* Create our secret Post on submission
*
* @since 1.0.0
*/
public function view_secret() {

wp_verify_nonce( 'view_secret_nonce', $_POST['view_secret_nonce'] );

$secret_key = trim( $_POST[ '_wp_http_referer' ], '/' ); // Get the key from the referrering page
$secret_key = explode( '/', $secret_key );
$secret = site_url( '/secret/view/' . $secret_key[1] );

wp_safe_redirect( $secret, 301, esc_attr__( 'Psst', 'psst' ) );
exit();
}

/**
* Delete our secret Post on submission
* @since 1.0.0
Expand Down
3 changes: 3 additions & 0 deletions templates/secret-confirmation.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
</button>
</div>
</div>
<div>
<strong><?php printf( __( 'Expires: %s', 'psst' ), esc_html( $secret_expiration_date ) ); ?></strong>
</div>
</div>
</div>
</div>
Expand Down
27 changes: 27 additions & 0 deletions templates/secret.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Secret Confirm View Template
*
* This template holds the secret confirmation button
* This should probably have a controller for an endpoint vs using admin-post.php
*
* @since 1.0.4
*/
?>
<div class="grid-container">
<div class="grid-x align-center">
<div class="cell small-12 medium-centered">
<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post" id="psst-secret-view">
<div class="grid-x">
<div class="cell small-12">
<p><?php esc_html_e( 'Once you click view, your secret will be revealed, onced viewed it will be removed from the system', 'psst' ); ?></p>
<input type="hidden" name="action" value="psst_view_secret" />
<input type="hidden" name="confirm_secret" value="true" />
<?php wp_nonce_field( 'view_secret', 'view_secret_nonce' ); ?>
<button type="submit" class="button primary expanded"><?php esc_html_e( 'View Secret', 'psst' ); ?></button>
</div>
</div>
</form>
</div>
</div>
</div>

0 comments on commit 5444bc5

Please sign in to comment.