diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php index d784a8a67..249da48cd 100644 --- a/lib/Controller/ShareController.php +++ b/lib/Controller/ShareController.php @@ -54,6 +54,21 @@ public function add(int $pollId, string $type, string $userId = '', string $disp return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, $type, $userId, $displayName, $emailAddress)]); } + /** + * Add share + * @param int $pollId poll id + * @param string $type Share type + * @param string $userId User id + * @param string $displayName Displayname of user + * @param string $emailAddress Email address of user + */ + #[NoAdminRequired] + #[OpenAPI(OpenAPI::SCOPE_IGNORE)] + #[FrontpageRoute(verb: 'POST', url: '/poll/{pollId}/publicshare')] + public function addPublicShare(int $pollId): JSONResponse { + return $this->responseCreate(fn () => ['share' => $this->shareService->add($pollId, Share::TYPE_PUBLIC)]); + } + /** * Change the contraints for email addresses in public polls * @param string $token Share token diff --git a/lib/Model/Settings/AppSettings.php b/lib/Model/Settings/AppSettings.php index 90af209c5..610ab767d 100644 --- a/lib/Model/Settings/AppSettings.php +++ b/lib/Model/Settings/AppSettings.php @@ -239,7 +239,6 @@ public function jsonSerialize(): array { self::SETTING_IMPRINT_URL => $this->appConfig->getValueString(AppConstants::APP_ID, self::SETTING_IMPRINT_URL), self::SETTING_PRIVACY_URL => $this->appConfig->getValueString(AppConstants::APP_ID, self::SETTING_PRIVACY_URL), self::SETTING_UPDATE_TYPE => $this->getUpdateType(), - 'storedKeys' => $this->appConfig->getKeys(AppConstants::APP_ID), 'usePrivacyUrl' => $this->getUsePrivacyUrl(), 'useImprintUrl' => $this->getUseImprintUrl(), 'defaultPrivacyUrl' => $this->appConfig->getValueString('theming', 'privacyUrl'), diff --git a/lib/Service/MailService.php b/lib/Service/MailService.php index ee929ec91..4b89319b6 100644 --- a/lib/Service/MailService.php +++ b/lib/Service/MailService.php @@ -102,7 +102,7 @@ public static function extractEmailAddressAndName($eMailString): array { preg_match(self::REGEX_PARSE_MAIL_AND_NAME, $eMailString, $matches); // Check if the found element is a valid email address - $emailAddress = boolval($matches[1]) ? trim($matches[1]) : null; + $emailAddress = !empty($matches[1]) ? trim($matches[1]) : null; if ($emailAddress !== null && filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) { // Extract the name based on the input string diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php index e86741ace..7fdbcac74 100644 --- a/lib/Service/SettingsService.php +++ b/lib/Service/SettingsService.php @@ -53,7 +53,7 @@ public function writeAppSettings(array $settingsArray): void { $this->appConfig->setValueArray(AppConstants::APP_ID, AppSettings::SETTING_POLL_CREATION_GROUPS, array_column($settingsArray[AppSettings::SETTING_POLL_CREATION_GROUPS], 'id')); $this->appConfig->setValueArray(AppConstants::APP_ID, AppSettings::SETTING_POLL_DOWNLOAD_GROUPS, array_column($settingsArray[AppSettings::SETTING_POLL_DOWNLOAD_GROUPS], 'id')); - $this->appConfig->setValueInt(AppConstants::APP_ID, AppSettings::SETTING_AUTO_ARCHIVE_OFFSET, $settingsArray[AppSettings::SETTING_AUTO_ARCHIVE_OFFSET]); + $this->appConfig->setValueInt(AppConstants::APP_ID, AppSettings::SETTING_AUTO_ARCHIVE_OFFSET, intval($settingsArray[AppSettings::SETTING_AUTO_ARCHIVE_OFFSET])); $this->appConfig->setValueString(AppConstants::APP_ID, AppSettings::SETTING_UPDATE_TYPE, $settingsArray[AppSettings::SETTING_UPDATE_TYPE]); $this->appConfig->setValueString(AppConstants::APP_ID, AppSettings::SETTING_PRIVACY_URL, $settingsArray[AppSettings::SETTING_PRIVACY_URL]); diff --git a/src/Api/modules/shares.js b/src/Api/modules/shares.js index b74d3c0c4..0c0c70fb8 100644 --- a/src/Api/modules/shares.js +++ b/src/Api/modules/shares.js @@ -14,12 +14,20 @@ const shares = { }) }, - addShare(pollId, user) { + addUserShare(pollId, user) { return httpInstance.request({ method: 'POST', url: `poll/${pollId}/share`, - data: { ...user }, - cancelToken: cancelTokenHandlerObject[this.addShare.name].handleRequestCancellation().token, + data: user, + cancelToken: cancelTokenHandlerObject[this.addUserShare.name].handleRequestCancellation().token, + }) + }, + + addPublicShare(pollId) { + return httpInstance.request({ + method: 'POST', + url: `poll/${pollId}/publicshare`, + cancelToken: cancelTokenHandlerObject[this.addPublicShare.name].handleRequestCancellation().token, }) }, diff --git a/src/components/Base/modules/InputDiv.vue b/src/components/Base/modules/InputDiv.vue index 842360498..f9d25a7ec 100644 --- a/src/components/Base/modules/InputDiv.vue +++ b/src/components/Base/modules/InputDiv.vue @@ -150,7 +150,7 @@ if (model.value !== nextValue) { model.value = nextValue - emit('submit') + emit('change') } } @@ -163,7 +163,7 @@ if (model.value !== nextValue) { model.value = nextValue - emit('submit') + emit('change') } } @@ -173,7 +173,6 @@ - diff --git a/src/components/Configuration/ConfigOptionLimit.vue b/src/components/Configuration/ConfigOptionLimit.vue index 5be104f5c..07aea7947 100644 --- a/src/components/Configuration/ConfigOptionLimit.vue +++ b/src/components/Configuration/ConfigOptionLimit.vue @@ -47,7 +47,6 @@ inputmode="numeric" :num-min="1" use-num-modifiers - @submit="pollStore.write()" @change="pollStore.write()" /> diff --git a/src/components/Settings/AdminSettings/AdminCombo.vue b/src/components/Settings/AdminSettings/AdminCombo.vue index c9b9b76a4..adc58b3ef 100644 --- a/src/components/Settings/AdminSettings/AdminCombo.vue +++ b/src/components/Settings/AdminSettings/AdminCombo.vue @@ -31,7 +31,7 @@ :multiple="true" :loading="appSettingsStore.status.loadingGroups" :placeholder="t('polls', 'Leave empty to disable globally')" - @option:selected="appSettingsStore.write()" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Settings/AdminSettings/AdminPollCreation.vue b/src/components/Settings/AdminSettings/AdminPollCreation.vue index 3d81cfdcf..efc6d77fd 100644 --- a/src/components/Settings/AdminSettings/AdminPollCreation.vue +++ b/src/components/Settings/AdminSettings/AdminPollCreation.vue @@ -30,7 +30,7 @@ :multiple="true" :loading="isLoading" :placeholder="t('polls', 'Leave empty to disable globally')" - @option:selected="appSettingsStore.write()" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Settings/AdminSettings/AdminPollDownload.vue b/src/components/Settings/AdminSettings/AdminPollDownload.vue index 76a14011f..f5a39e87e 100644 --- a/src/components/Settings/AdminSettings/AdminPollDownload.vue +++ b/src/components/Settings/AdminSettings/AdminPollDownload.vue @@ -31,7 +31,7 @@ :multiple="true" :loading="isLoading" :placeholder="t('polls', 'Leave empty to disable globally')" - @option:selected="appSettingsStore.write()" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Settings/AdminSettings/AdminShareOpenPoll.vue b/src/components/Settings/AdminSettings/AdminShareOpenPoll.vue index ce5d8853c..60d9b5aaf 100644 --- a/src/components/Settings/AdminSettings/AdminShareOpenPoll.vue +++ b/src/components/Settings/AdminSettings/AdminShareOpenPoll.vue @@ -32,6 +32,7 @@ :multiple="true" :loading="isLoading" :placeholder="t('polls', 'Leave empty to disable globally')" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Settings/AdminSettings/AdminSharePublicCreate.vue b/src/components/Settings/AdminSettings/AdminSharePublicCreate.vue index ab8985f7d..818b4e625 100644 --- a/src/components/Settings/AdminSettings/AdminSharePublicCreate.vue +++ b/src/components/Settings/AdminSettings/AdminSharePublicCreate.vue @@ -31,6 +31,7 @@ :multiple="true" :loading="isLoading" :placeholder="t('polls', 'Leave empty to disable globally')" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Settings/AdminSettings/AdminShowMailAddresses.vue b/src/components/Settings/AdminSettings/AdminShowMailAddresses.vue index 482668dd7..64d9c78a3 100644 --- a/src/components/Settings/AdminSettings/AdminShowMailAddresses.vue +++ b/src/components/Settings/AdminSettings/AdminShowMailAddresses.vue @@ -31,7 +31,7 @@ :multiple="true" :loading="isLoading" :placeholder="t('polls', 'Leave empty to disable globally.')" - @option:selected="appSettingsStore.write()" + @update:model-value="appSettingsStore.write()" @search="appSettingsStore.loadGroups" /> diff --git a/src/components/Shares/SharePublicAdd.vue b/src/components/Shares/SharePublicAdd.vue index 322abaf38..652853c20 100644 --- a/src/components/Shares/SharePublicAdd.vue +++ b/src/components/Shares/SharePublicAdd.vue @@ -41,7 +41,7 @@ async function addPublicShare() { try { - await sharesStore.add(user) + await sharesStore.addPublicShare() } catch { showError(t('polls', 'Error adding public link')) } diff --git a/src/components/User/UserSearch.vue b/src/components/User/UserSearch.vue index 7c8d7e23a..e2885afc9 100644 --- a/src/components/User/UserSearch.vue +++ b/src/components/User/UserSearch.vue @@ -14,6 +14,7 @@ import { AppSettingsAPI } from '../../Api/index.js' import { Logger } from '../../helpers/index.ts' import { useSharesStore } from '../../stores/shares.ts' +import { User } from '../../Types/index.ts' const sharesStore = useSharesStore() const users = ref([]) @@ -39,14 +40,10 @@ } }, 250) - async function clickAdd(payload) { + async function clickAdd(user: User) { + Logger.debug('Adding share clicAdd', user) try { - await sharesStore.add({ - user: { - ...payload, - }, - }, - ) + await sharesStore.add(user) } catch { showError(t('polls', 'Error while adding share')) } diff --git a/src/stores/shares.ts b/src/stores/shares.ts index fb3b2ed3d..c004a5e67 100644 --- a/src/stores/shares.ts +++ b/src/stores/shares.ts @@ -90,8 +90,9 @@ export const useSharesStore = defineStore('shares', { async add(user: User ): Promise { const sessionStore = useSessionStore() + try { - await SharesAPI.addShare(sessionStore.route.params.id, user) + await SharesAPI.addUserShare(sessionStore.route.params.id, user) } catch (error) { if (error?.code === 'ERR_CANCELED') return Logger.error('Error writing share', { error, payload: user }) @@ -101,6 +102,19 @@ export const useSharesStore = defineStore('shares', { } }, + async addPublicShare(): Promise { + const sessionStore = useSessionStore() + try { + await SharesAPI.addPublicShare(sessionStore.route.params.id) + } catch (error) { + if (error?.code === 'ERR_CANCELED') return + Logger.error('Error writing share', { error}) + throw error + } finally { + this.load() + } + }, + update(payload: { share: Share }): void { const foundIndex = this.list.findIndex((share: Share) => share.id === payload.share.id) Object.assign(this.list[foundIndex], payload.share)