Skip to content
7 changes: 0 additions & 7 deletions admin/godam-transcoder-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -736,16 +736,9 @@ function rtgodam_get_localize_array() {
* Get Current User.
*/
$current_user = wp_get_current_user();
$email_id = '';

$localize_array['userId'] = $current_user->ID;

if ( ! empty( (array) $current_user->data ) ) {

$email_id = $current_user->data->user_email;
$localize_array['emailId'] = $email_id;
}

$localize_array['siteId'] = get_current_blog_id();

if ( get_post_type() ) { // godam-coverage-ignore -- No argument: same current-page-type check as postTitle above, not an explicit attachment lookup.
Expand Down
2 changes: 0 additions & 2 deletions assets/src/js/godam-player/analytics-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ export function buildAnalyticsRequestBody( {
endpoint,
token,
userId,
emailId,
locationIP,
isPost,
isPage,
Expand Down Expand Up @@ -240,7 +239,6 @@ export function buildAnalyticsRequestBody( {
user_token: userToken,
wp_user_id: parseInt( userId, 10 ) || 0,
account_token: token || '',
email: emailId || '',
visitor_timestamp: visitorTimestamp || Date.now(),
visit_entry_action_url: window.location.href,
visit_entry_action_name: document.title,
Expand Down
19 changes: 19 additions & 0 deletions assets/src/js/godam-player/analytics-helpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ const setParams = ( overrides = {} ) => {

const build = ( opts ) => buildAnalyticsRequestBody( { type: 1, ...opts } );

describe( 'buildAnalyticsRequestBody — viewer identity', () => {
beforeEach( () => {
setParams();
} );

it( 'does not send the viewer email, even when the page still carries one', () => {
// setParams() leaves emailId on the page, as a page cached by an older
// plugin version would.
const { body } = build( {} );
expect( body ).not.toHaveProperty( 'email' );
expect( JSON.stringify( body ) ).not.toContain( 'a@b.test' );
} );

it( 'still sends the WordPress user id', () => {
const { body } = build( {} );
expect( body.wp_user_id ).toBe( 1 );
} );
} );

describe( 'buildAnalyticsRequestBody — placement attribution', () => {
beforeEach( () => {
setParams();
Expand Down
2 changes: 1 addition & 1 deletion assets/src/js/godam-player/engagement.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jest.mock( '@wordpress/api-fetch', () => {

// engagement.js reads window.godamData once, when it loads.
window.godamData = {
currentLoggedInUserData: { email: 'viewer@example.com', name: 'Viewer', type: 'user' },
currentLoggedInUserData: { name: 'Viewer', type: 'user' },
loginUrl: '/wp-login.php',
registrationUrl: '/wp-login.php?action=register',
defaultAvatar: 'https://avatar.test/default',
Expand Down
2 changes: 1 addition & 1 deletion inc/classes/shortcodes/class-godam-player.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ public function register_scripts() {
// the requested video is not rendered on the page.
'embedBaseUrl' => home_url( '/' ),
'hostPostId' => get_the_ID() ? get_the_ID() : '',
'currentLoggedInUserData' => rtgodam_get_current_logged_in_user_data(),
'currentLoggedInUserData' => rtgodam_get_current_user_data_for_page(),
'loginUrl' => apply_filters( 'rtgodam_site_login_url', wp_login_url() . '?redirect_to=' . rawurlencode( get_permalink() ) ),
'registrationUrl' => apply_filters( 'rtgodam_site_registration_url', wp_registration_url() . '&redirect_to=' . rawurlencode( get_permalink() ) ),
'defaultAvatar' => get_avatar_url( 0 ),
Expand Down
19 changes: 19 additions & 0 deletions inc/helpers/custom-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,25 @@ function rtgodam_get_current_logged_in_user_data() {
);
}

/**
* Retrieves the current user's details for printing into a front-end page.
*
* Only the display name and whether someone is signed in: the page needs nothing
* else, and the REST routes that need the email read it on the server. The list
* of fields is fixed here, so a field added later to
* rtgodam_get_current_logged_in_user_data() is not printed by accident.
*
* @since n.e.x.t
*
* @return array An associative array containing 'name' and 'type' of the user or guest.
*/
function rtgodam_get_current_user_data_for_page() {
return array_intersect_key(
rtgodam_get_current_logged_in_user_data(),
array_flip( array( 'name', 'type' ) )
);
}

/**
* Retrieves a cached value by key.
*
Expand Down
10 changes: 4 additions & 6 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
=== GoDAM - Organize WordPress Media Library & File Manager with Unlimited Folders for Images, Videos & more ===
Contributors: rtcamp, elifvish, subodhrajpopat, kuldipchaudhary, prachigarg19, juzar, geekofshire, nazmulhassann20, joelabreo, mi5t4n, abhinavbelhekar03, gautam23, mukulsingh27, hbhalodia, kishu7270, opurockey, utsavladani, whiteshadow01, ahmarzaidi, im3dabasia1, rudrakshigupta, sabbir1991, shreyasikhar26, akrocks
Tags: transcoder, video, media library, folders, file manager
Expand Down Expand Up @@ -301,15 +301,13 @@

1. IP Address

2. Email
2. Author of the post's display name

3. Author of the post's display name
3. Browser version, name, and browser language

4. Browser version, name, and browser language
4. User Agent String

5. User Agent String

6. The operating system of the user's device (e.g., Windows, macOS, Android)
5. The operating system of the user's device (e.g., Windows, macOS, Android)

When Data is Sent:

Expand Down
84 changes: 84 additions & 0 deletions tests/php/ViewerEmailNotInPageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* Unit tests for the values GoDAM prints into every front-end page.
*
* rtgodam_get_localize_array() builds the `videoAnalyticsParams` object that is
* written into every front-end page. It is the same for everyone who loads the
* page, so it carries the signed-in user's id and nothing else about them: no
* email address.
*
* @package GoDAM
*/

namespace RTGODAM\Tests;

use PHPUnit\Framework\TestCase;

/**
* Each test runs in its own process: loading the transcoder functions file
* registers hooks as it loads, and EarlyTranslationHooksTest checks exactly that
* on the first load in the shared process.
*
* The page-tag stubs load there too, for the same reason.
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class ViewerEmailNotInPageTest extends TestCase {

private const VIEWER_EMAIL = 'test-w1-viewer@example.com';

protected function setUp(): void {
parent::setUp();

require_once dirname( __DIR__ ) . '/stubs/template-tags.php';
require_once dirname( __DIR__, 2 ) . '/admin/godam-transcoder-functions.php';

$GLOBALS['rtgodam_stub'] = array(
'user' => array(
'id' => 7,
'email' => self::VIEWER_EMAIL,
'name' => 'Viewer',
),
'options' => array(
'rtgodam-account-token' => 'verified-account',
),
);
}

protected function tearDown(): void {
unset( $GLOBALS['rtgodam_stub'] );
parent::tearDown();
}

public function test_signed_in_viewers_email_is_not_in_the_page_params(): void {
$params = rtgodam_get_localize_array();

$this->assertArrayNotHasKey( 'emailId', $params );
$this->assertStringNotContainsString( self::VIEWER_EMAIL, (string) wp_json_encode( $params ) );
}

public function test_player_page_data_for_a_signed_in_viewer_has_no_email(): void {
$data = rtgodam_get_current_user_data_for_page();

$this->assertArrayNotHasKey( 'email', $data );
$this->assertStringNotContainsString( self::VIEWER_EMAIL, (string) wp_json_encode( $data ) );
$this->assertSame( 'Viewer', $data['name'] );
$this->assertSame( 'user', $data['type'] );
}

public function test_the_server_side_user_data_still_has_the_email(): void {
// The comments routes read the address on the server; only the page copy drops it.
$this->assertSame( self::VIEWER_EMAIL, rtgodam_get_current_logged_in_user_data()['email'] );
}

public function test_page_params_keep_what_analytics_still_needs(): void {
$params = rtgodam_get_localize_array();

$this->assertSame( 7, $params['userId'] );
$this->assertSame( 1, $params['siteId'] );
$this->assertSame( 'https://analytics.test', $params['endpoint'] );
$this->assertSame( 'verified-account', $params['token'] );
$this->assertSame( 500, $params['postId'] );
}
}
3 changes: 3 additions & 0 deletions tests/stubs/engagement-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ function wp_get_current_user() { // phpcs:ignore WordPress.NamingConventions.Pre
$user = $GLOBALS['rtgodam_stub']['user'] ?? array();

return (object) array(
'ID' => $user['id'] ?? 0,
'user_email' => $user['email'] ?? '',
'display_name' => $user['name'] ?? '',
// Like WordPress: an empty object for a visitor who is not signed in.
'data' => (object) ( isset( $user['email'] ) ? array( 'user_email' => $user['email'] ) : array() ),
);
}
}
Expand Down
116 changes: 116 additions & 0 deletions tests/stubs/template-tags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php
/**
* Narrow template-tag stubs for the pure (no-WordPress) unit suite.
*
* Used by the tests that call rtgodam_get_localize_array(), which reads the
* current request's post, page type and site. Each stub returns a fixed
* front-end page and is guarded against redeclaring a function another stub
* file already defines. Load this file from a test's setUp() in a separate
* process (see ViewerEmailNotInPageTest), so the stubs do not reach other tests.
*
* @package GoDAM
*/

if ( ! defined( 'RTGODAM_ANALYTICS_BASE' ) ) {
define( 'RTGODAM_ANALYTICS_BASE', 'https://analytics.test' );
}

if ( ! function_exists( 'is_single' ) ) {

/**
* @return bool
*/
function is_single() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return false;
}
}

if ( ! function_exists( 'is_page' ) ) {

/**
* @return bool
*/
function is_page() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return true;
}
}

if ( ! function_exists( 'is_archive' ) ) {

/**
* @return bool
*/
function is_archive() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return false;
}
}

if ( ! function_exists( 'get_the_title' ) ) {

/**
* @return string
*/
function get_the_title() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return 'Host Page';
}
}

if ( ! function_exists( 'get_current_blog_id' ) ) {

/**
* @return int
*/
function get_current_blog_id() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return 1;
}
}

if ( ! function_exists( 'get_post_type' ) ) {

/**
* @return string
*/
function get_post_type() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return 'page';
}
}

if ( ! function_exists( 'get_the_ID' ) ) {

/**
* @return int
*/
function get_the_ID() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound,WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid -- stub mirroring the WP function.
return 500;
}
}

if ( ! function_exists( 'get_the_author' ) ) {

/**
* @return string
*/
function get_the_author() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return 'someone';
}
}

if ( ! function_exists( 'get_the_category' ) ) {

/**
* @return array
*/
function get_the_category() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return array();
}
}

if ( ! function_exists( 'get_the_tags' ) ) {

/**
* @return bool
*/
function get_the_tags() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- stub mirroring the WP function.
return false;
}
}
Loading