public function getAllowedFields($details = false)
    {
        if (null === $this->allowedFields) {
            $cache = $this->cacheStorageHelper();
            if ($cachedAllowedFields = $cache->get('allowedFields', self::CACHE_TTL)) {
                $this->allowedFields = $cachedAllowedFields;
            }
            if (!$this->allowedFields) {
                try {
                    // Exclude company fields as they cannot be created/related on insert due to performance implications.
                    $entities = $this->fieldModel->getEntities(
                        [
                            'filter'         => [
                                'force' => [
                                    [
                                        'column' => 'f.isPublished',
                                        'expr'   => 'eq',
                                        'value'  => true,
                                    ],
                                    [
                                        'column' => 'f.object',
                                        'expr'   => 'neq',
                                        'value'  => 'company',
                                    ],
                                ],
                            ],
                            'hydration_mode' => 'HYDRATE_ARRAY',
                        ]
                    );

                    // Also build an inclusive array for API and output.
                    $allowedFields = [];
                    foreach ($entities as $field) {
                        $allowedFields[$field['alias']] = [
                            'alias'        => $field['alias'],
                            'type'         => $field['type'],
                            'defaultValue' => $field['defaultValue'],
                            'label'        => $field['label'],
                        ];
                    }
                    // Add IP as an allowed import field.
                    $allowedFields['ip'] = [
                        'alias'        => 'ip',
                        'type'         => 'text',
                        'defaultValue' => '',
                        'label'        => 'IP Addresses (comma delimited)',
                    ];

                    // Get available UTM fields and their setters.
                    foreach ($this->getUtmSetters() as $q => $v) {
                        $allowedFields[$q] = [
                            'alias'        => $q,
                            'type'         => 'text',
                            'defaultValue' => '',
                            'label'        => str_replace(
                                ['Utm', 'Set'],
                                ['UTM', ''],
                                ucwords(str_replace('_', ' ', $q))
                            ),
                        ];
                    }

                    // Get available Device fields and their setters.
                    foreach ($this->getDeviceSetters() as $q => $v) {
                        $allowedFields[$q] = [
                            'alias'        => $q,
                            'type'         => 'text',
                            'defaultValue' => '',
                            'label'        => ucwords(str_replace('_', ' ', $q)),
                        ];
                    }

                    unset($allowedFields['attribution'], $allowedFields['attribution_date']);

                    uksort($allowedFields, 'strnatcmp');

                    $this->allowedFields = $allowedFields;

                    $cache->set('allowedFields', $this->allowedFields, self::CACHE_TTL);
                } catch (\Exception $exception) {
                    $this->handleException($exception);
                }
            }
            if ($this->allowedFields && !$this->allowedFieldLabels) {
                $allowedFieldLabels = [];
                foreach ($this->allowedFields as $key => $value) {
                    $allowedFieldLabels[$key] = $value['label'];
                }
                $this->allowedFieldLabels = $allowedFieldLabels;
            }
        }

        return $details ? $this->allowedFields : $this->allowedFieldLabels;
    }