#!/usr/local/cpanel/3rdparty/bin/perl
#                                      Copyright 2026 WebPros International, LLC
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited.

package autofixer2::fix_filemanager_analytics_consent;

use strict;
use warnings;

BEGIN { unshift @INC, '/usr/local/cpanel'; }

exit run() unless caller;

# CPANEL-51678 / CPANEL-52793
#
# base/frontend/jupiter/filemanager/upload-ajax.html.tt shipped with
# canTrackUserAnalytics and isUserAnalyticsRequiredByLeika hardcoded, which
# bypassed Cpanel::Analytics::can_track_user_analytics() and caused anonymous
# Mixpanel events to fire for users who had not consented to analytics.
#
# Replacing both values with their template variables lets the upstream
# consent check (mixpanel-utils.service.ts) call mixpanel.opt_out_tracking()
# for non-consenting users.  That single SDK-level gate makes every
# subsequent window.mixpanel.track() / track_links() call on the page a
# no-op, so no additional per-call-site guards are required.
#
# Scoped to cPanel 132-136.  138 already carries the forward-merged fix
# before any customer build shipped.

sub _patches {
    return (
        {
            file    => "/usr/local/cpanel/base/frontend/jupiter/filemanager/upload-ajax.html.tt",
            desc    => 'upload popup canTrackUserAnalytics bypass',
            find    => 'canTrackUserAnalytics => 1,',
            replace => 'canTrackUserAnalytics => can_track_user_analytics,',
        },
        {
            file    => "/usr/local/cpanel/base/frontend/jupiter/filemanager/upload-ajax.html.tt",
            desc    => 'upload popup isUserAnalyticsRequiredByLeika bypass',
            find    => 'isUserAnalyticsRequiredByLeika => 0,',
            replace => 'isUserAnalyticsRequiredByLeika => is_user_analytics_required_by_leika,',
        },
    );
}

sub run {
    return 0 unless supported_on_this_major( 132, 136 );

    my $status = 0;

    for my $patch ( _patches() ) {
        my $ok = _apply_patch($patch);
        $status = 1 unless $ok;
    }

    return $status;
}

sub supported_on_this_major {
    my ( $min_ver, $max_ver ) = @_;
    my $major = get_major_version();
    return 0 if $major < $min_ver;
    return 0 if $major > $max_ver;
    return 1;
}

sub get_major_version {
    my $major_version;
    if ( open( my $fh, '<', '/usr/local/cpanel/version' ) ) {
        my $full_version = <$fh>;
        close($fh);
        if ( length $full_version ) {
            chomp $full_version;
            ($major_version) = $full_version =~ /^[0-9]+\.([0-9]+)/;
        }
    }
    return $major_version || 30;
}

sub _apply_patch {
    my ($patch) = @_;

    unless ( -e $patch->{file} ) {
        print "$patch->{file}: not present, skipping '$patch->{desc}'.\n";
        return 1;
    }

    open( my $fh, '<', $patch->{file} )
      or do {
        warn "Cannot read $patch->{file} for '$patch->{desc}': $!\n";
        return 0;
      };
    my $content = do { local $/; <$fh> };
    close $fh;

    my $find  = quotemeta( $patch->{find} );
    my $count = ( $content =~ s/$find/$patch->{replace}/g );

    unless ($count) {
        print "$patch->{file}: already patched or pattern absent - '$patch->{desc}'.\n";
        return 1;
    }

    require Cpanel::FileUtils::Write;
    my $write_ok = eval {
        Cpanel::FileUtils::Write::overwrite( $patch->{file}, $content, 0644 );
        1;
    };
    unless ($write_ok) {
        warn "Failed to write $patch->{file} for '$patch->{desc}': $@\n";
        return 0;
    }

    print "$patch->{file}: applied '$patch->{desc}' ($count replacement(s)).\n";
    return 1;
}

1;
