HEX
Server: Microsoft-IIS/10.0
System: Windows NT ITPWINWEBSVR22 10.0 build 20348 (Windows Server 2022) AMD64
User: www.conferencesearch.co.uk (0)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: D:/web/matomo.vdk/plugins/PrivacyManager/vue/src/AnonymizeIp/AnonymizeIp.vue
<!--
  Matomo - free/libre analytics platform

  @link    https://matomo.org
  @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->

<template>
  <div v-form class="anonymizeSettings">
    <template v-if="idSiteSpecific">
      <Field
        uicontrol="radio"
        :name="`useSiteSpecificSettings${idSiteSpecific}`"
        :title="translate('PrivacyManager_SiteAnonymizationConfig')"
        v-model="actualUseSiteSpecificSettings"
        :options="useSiteSpecificSettingsOptions"
        :inline-help="useSiteSpecificSettingsHelpText"
      >
      </Field>
    </template>
    <template v-if="showSettings">
      <div class="anonymizeIpSettingsField">
        <Field
          uicontrol="checkbox"
          :name="`anonymizeIpSettings${idSiteSpecific}`"
          :title="translate('PrivacyManager_UseAnonymizeIp')"
          v-model="actualEnabled"
          :inline-help="anonymizeIpEnabledHelp"
          :extra-metadata="getExtraMetadataForField('ipAnonymizerEnabled')"
        >
        </Field>
      </div>
      <div v-show="actualEnabled">
        <div class="maskLengthField">
          <Field
            uicontrol="radio"
            :name="`maskLength${idSiteSpecific}`"
            :title="translate('PrivacyManager_AnonymizeIpMaskLengtDescription')"
            v-model="actualMaskLength"
            :options="maskLengthOptions"
            :inline-help="translate('PrivacyManager_GeolocationAnonymizeIpNote')"
            :extra-metadata="getExtraMetadataForField('ipAddressMaskLength')"
          >
          </Field>
        </div>
        <div class="useAnonymizedIpForVisitEnrichmentField">
          <Field
            uicontrol="radio"
            :name="`useAnonymizedIpForVisitEnrichment${idSiteSpecific}`"
            :title="translate('PrivacyManager_UseAnonymizedIpForVisitEnrichment')"
            v-model="actualUseAnonymizedIpForVisitEnrichment"
            :options="useAnonymizedIpForVisitEnrichmentOptions"
            :inline-help="translate('PrivacyManager_UseAnonymizedIpForVisitEnrichmentNote')"
            :extra-metadata="getExtraMetadataForField('useAnonymizedIpForVisitEnrichment')"
          >
          </Field>
        </div>
      </div>
      <div class="anonymizeUserIdField">
        <Field
          uicontrol="checkbox"
          :name="`anonymizeUserId${idSiteSpecific}`"
          :title="translate('PrivacyManager_PseudonymizeUserId')"
          v-model="actualAnonymizeUserId"
          :extra-metadata="getExtraMetadataForField('anonymizeUserId')"
        >
          <template v-slot:inline-help>
            {{ translate('PrivacyManager_PseudonymizeUserIdNote') }}
            <br/><br/>
            <em>{{ translate('PrivacyManager_PseudonymizeUserIdNote2') }}</em>
          </template>
        </Field>
      </div>
      <div class="anonymizeOrderIdField">
        <Field
          uicontrol="checkbox"
          :name="`anonymizeOrderId${idSiteSpecific}`"
          :title="translate('Ecommerce_UseAnonymizeOrderId')"
          v-model="actualAnonymizeOrderId"
          :inline-help="translate('Ecommerce_AnonymizeOrderIdNote')"
          :extra-metadata="getExtraMetadataForField('anonymizeOrderId')"
        >
        </Field>
      </div>
      <div v-if="!idSiteSpecific" class="forceCookielessTrackingField">
        <Field
          uicontrol="checkbox"
          name="forceCookielessTracking"
          :title="translate('PrivacyManager_ForceCookielessTracking')"
          v-model="actualForceCookielessTracking"
          :extra-metadata="getExtraMetadataForField('forceCookielessTracking')"
        >
          <template v-slot:inline-help>
            {{ translate('PrivacyManager_ForceCookielessTrackingDescription', trackerFileName) }}
            <br/><br/><em>{{ translate('PrivacyManager_ForceCookielessTrackingDescription2') }}</em>
            <span v-if="!trackerWritable">
              <br /><br />
              <p class='alert-warning alert'>
                {{ translate(
                'PrivacyManager_ForceCookielessTrackingDescriptionNotWritable',
                trackerFileName,
              ) }}
              </p>
            </span>
          </template>
        </Field>
      </div>
      <div class="anonymizeReferrerField">
        <Field
          uicontrol="select"
          :name="`anonymizeReferrer${idSiteSpecific}`"
          :title="translate('PrivacyManager_AnonymizeReferrer')"
          v-model="actualAnonymizeReferrer"
          :options="referrerAnonymizationOptions"
          :inline-help="translate('PrivacyManager_AnonymizeReferrerNote')"
          :extra-metadata="getExtraMetadataForField('anonymizeReferrer')"
        >
        </Field>
      </div>
      <div class="randomizeConfigIdField">
        <Field
          uicontrol="checkbox"
          :name="`randomizeConfigId${idSiteSpecific}`"
          :title="translate('PrivacyManager_UseRandomizeConfigId')"
          v-model="actualRandomizeConfigId"
          :inline-help="randomiseConfigIdHelpText"
          :extra-metadata="getExtraMetadataForField('randomizeConfigId')"
        >
        </Field>
      </div>
    </template>
    <div class="footer-buttons" v-if="!idSiteSpecific">
      <SaveButton
        @confirm="shouldSave()"
        :saving="isLoading"
      />
    </div>
    <PasswordConfirmation
      v-model="showPasswordConfirmation"
      @confirmed="save"
      @aborted="abortPasswordConfirmation"
    >
      <h2>{{ passwordConfirmationTitle }}</h2>
      <p>{{ translate('PrivacyManager_ConfirmConfigRandomisationExplanation') }}</p>
    </PasswordConfirmation>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import {
  translate,
  AjaxHelper,
  MatomoUrl,
  NotificationsStore,
} from 'CoreHome';
import {
  Form,
  Field,
  PasswordConfirmation,
  SaveButton,
} from 'CorePluginsAdmin';

interface AnonymizeIpState {
  isLoading: boolean;
  actualEnabled: boolean;
  actualUseSiteSpecificSettings: string;
  actualMaskLength: number;
  actualUseAnonymizedIpForVisitEnrichment: number;
  actualAnonymizeUserId: boolean;
  actualAnonymizeOrderId: boolean;
  actualForceCookielessTracking: boolean;
  actualAnonymizeReferrer?: string;
  actualRandomizeConfigId: boolean;
  showPasswordConfirmation: boolean;
}

type TMaybeObject = Record<string, unknown> | undefined;

function boolToInt(value?: string|number|boolean): number {
  return value === true || value === 1 || value === '1' ? 1 : 0;
}

const SYSTEM_SETTINGS = 'system';
const SITE_SPECIFIC_SETTINGS = 'site-specific';

export default defineComponent({
  props: {
    ipAnonymizerEnabled: Boolean,
    anonymizeUserId: Boolean,
    ipAddressMaskLength: {
      type: [Number, String],
      required: true,
    },
    useAnonymizedIpForVisitEnrichment: {
      type: [Boolean, String, Number],
      default: 0,
    },
    anonymizeOrderId: Boolean,
    forceCookielessTracking: Boolean,
    anonymizeReferrer: String,
    maskLengthOptions: {
      type: Array,
      required: true,
    },
    useAnonymizedIpForVisitEnrichmentOptions: {
      type: Array,
      required: true,
    },
    trackerFileName: {
      type: String,
      required: true,
    },
    trackerWritable: {
      type: Boolean,
      required: true,
    },
    referrerAnonymizationOptions: {
      type: Object,
      required: true,
    },
    randomizeConfigId: Boolean,
    idSiteSpecific: {
      type: [String, Number],
    },
    useSiteSpecificSettings: {
      type: Boolean,
      default: false,
    },
    triggerSave: {
      type: Boolean,
      default: false,
    },
    extraMetadata: {
      type: Object,
      default: () => ({}),
    },
  },
  components: {
    Field,
    PasswordConfirmation,
    SaveButton,
  },
  directives: {
    Form,
  },
  emits: ['updated', 'aborted'],
  data(): AnonymizeIpState {
    return {
      isLoading: false,
      actualEnabled: this.ipAnonymizerEnabled,
      actualUseSiteSpecificSettings: this.getActualUseSiteSpecificSettings(),
      actualMaskLength: +this.ipAddressMaskLength,
      actualUseAnonymizedIpForVisitEnrichment: boolToInt(
        this.useAnonymizedIpForVisitEnrichment,
      ),
      actualAnonymizeUserId: !!this.anonymizeUserId,
      actualAnonymizeOrderId: !!this.anonymizeOrderId,
      actualForceCookielessTracking: !!this.forceCookielessTracking,
      actualAnonymizeReferrer: this.anonymizeReferrer,
      actualRandomizeConfigId: !!this.randomizeConfigId,
      showPasswordConfirmation: false,
    };
  },
  methods: {
    shouldSave() {
      if (this.showSettings && this.actualRandomizeConfigId) {
        this.showPasswordConfirmation = true;
      } else {
        this.save();
      }
    },
    abortPasswordConfirmation() {
      this.$emit('aborted');
    },
    save(password?: string) {
      this.isLoading = true;

      const postParams: QueryParameters = {
        anonymizeIPEnable: boolToInt(this.actualEnabled),
        anonymizeUserId: boolToInt(this.actualAnonymizeUserId),
        anonymizeOrderId: boolToInt(this.actualAnonymizeOrderId),
        forceCookielessTracking: this.idSiteSpecific
          ? undefined
          : boolToInt(this.actualForceCookielessTracking),
        anonymizeReferrer: this.actualAnonymizeReferrer ? this.actualAnonymizeReferrer : '',
        ipAddressMaskLength: this.actualMaskLength,
        useAnonymizedIpForVisitEnrichment: this.actualUseAnonymizedIpForVisitEnrichment,
        randomizeConfigId: boolToInt(this.actualRandomizeConfigId),
        idSiteSpecific: this.idSiteSpecific ? this.idSiteSpecific : undefined,
        useSiteSpecificSettings: this.idSiteSpecific
          ? boolToInt(this.isSiteSpecificSettingsEnabled)
          : undefined,
      };

      if (password) {
        postParams.passwordConfirmation = password;
      }

      AjaxHelper.post(
        {
          module: 'API',
          method: 'PrivacyManager.setAnonymizeIpSettings',
        },
        postParams,
      ).then(() => {
        if (!this.idSiteSpecific) {
          const notificationInstanceId = NotificationsStore.show({
            message: translate('CoreAdminHome_SettingsSaveSuccess'),
            context: 'success',
            id: 'privacyManagerSettings',
            type: 'toast',
          });
          NotificationsStore.scrollToNotification(notificationInstanceId);
        }
        this.$emit('updated');
      }).catch(() => {
        this.$emit('aborted');
      }).finally(() => {
        this.isLoading = false;
      });
    },
    getActualUseSiteSpecificSettings(): string {
      return (this.idSiteSpecific && this.useSiteSpecificSettings)
        ? SITE_SPECIFIC_SETTINGS
        : SYSTEM_SETTINGS;
    },
    randomiseConfigIdHelpText() {
      const helpText = translate('PrivacyManager_RandomizeConfigIdNote');
      const helpTextWarning = translate(
        'PrivacyManager_RandomizeConfigIdNoteWarning',
        '<strong>',
        '</strong>',
      );

      return `${helpText}<br><br>${helpTextWarning}`;
    },
    getExtraMetadataForField(fieldName: string): TMaybeObject {
      return this.extraMetadata?.[fieldName];
    },
  },
  computed: {
    anonymizeIpEnabledHelp() {
      const inlineHelp1 = translate('PrivacyManager_AnonymizeIpInlineHelp');
      const inlineHelp2 = translate('PrivacyManager_AnonymizeIpDescription');
      return `${inlineHelp1} ${inlineHelp2}`;
    },
    passwordConfirmationTitle() {
      if (this.idSiteSpecific) {
        return translate('PrivacyManager_ConfirmConfigRandomisationEnabledPerSite');
      }
      return translate('PrivacyManager_ConfirmConfigRandomisationEnabled');
    },
    useSiteSpecificSettingsHelpText(): string {
      const link = `?${MatomoUrl.stringify({
        ...MatomoUrl.urlParsed.value,
        module: 'PrivacyManager',
        action: 'privacySettings',
      })}`;
      return translate(
        'PrivacyManager_UseSiteSpecificSettingsHelpText',
        `<a href="${link}" rel="noreferrer noopener" target="_blank">`,
        '</a>',
        translate('PrivacyManager_UseSiteSpecificSettings'),
      );
    },
    showSettings(): boolean {
      return !this.idSiteSpecific || this.isSiteSpecificSettingsEnabled;
    },
    isSiteSpecificSettingsEnabled(): boolean {
      return (
        this.idSiteSpecific
        && (this.actualUseSiteSpecificSettings === SITE_SPECIFIC_SETTINGS)
      ) as boolean;
    },
    useSiteSpecificSettingsOptions() {
      return [
        {
          value: translate('PrivacyManager_UseSystemSettings'),
          key: SYSTEM_SETTINGS,
        },
        {
          value: translate('PrivacyManager_UseSiteSpecificSettings'),
          key: SITE_SPECIFIC_SETTINGS,
        },
      ];
    },
  },
  watch: {
    triggerSave(newValue) {
      if (newValue) {
        this.shouldSave();
      }
    },
  },
});
</script>