Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--css/authenticate.css53
-rw-r--r--src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue32
-rw-r--r--src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue67
-rw-r--r--src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue3
-rw-r--r--src/components/RightSidebar/RightSidebar.vue43
-rw-r--r--src/services/conversationsService.js11
-rw-r--r--templates/authenticate.php10
7 files changed, 157 insertions, 62 deletions
diff --git a/css/authenticate.css b/css/authenticate.css
deleted file mode 100644
index 781d9ea03..000000000
--- a/css/authenticate.css
+++ /dev/null
@@ -1,53 +0,0 @@
-form fieldset {
- display: flex !important;
- flex-direction: column;
-}
-
-#password {
- margin-right: 0 !important;
- height: 45px;
- box-sizing: border-box;
- flex: 1 1 auto;
- width: 100% !important;
- min-width: 0; /* FF hack for to override default value */
-
- /* The padding needs to be set here instead of for "input[type="password"]"
- * elements to prevent being overriden by a more specific rule in the
- * server. */
- padding-right: 44px;
-}
-
-input[type="password"]:focus + .icon-confirm:not(:disabled) {
- opacity: .6;
-}
-
-input[type="password"] + .icon-confirm {
- position: absolute;
- right: 15px;
-
- /* Needed to honour the height set below for "input[type='submit']" by
- * overriding a rule set in the server. */
- height: 45px;
-
- border: none;
- /* Needed to override an important rule set in the server. */
- background-color: transparent !important;
-
- opacity: .3;
-}
-
-input[type="password"] + .icon-confirm:hover:not(:disabled),
-input[type="password"] + .icon-confirm:focus:not(:disabled),
-input[type="password"] + .icon-confirm:active:not(:disabled) {
- opacity: 1;
-}
-
-input[type='submit'] {
- width: 45px;
- height: 45px;
- margin-left: 0 !important;
-}
-
-fieldset > p {
- display: inline-flex;
-}
diff --git a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
index 10141074f..99fe8fbda 100644
--- a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
+++ b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
@@ -45,6 +45,18 @@
<SetConversationType
v-model="isPublic"
:conversation-name="conversationName" />
+ <template v-if="isPublic">
+ <input
+ id="password-checkbox"
+ type="checkbox"
+ class="checkbox"
+ :checked="passwordProtect"
+ @input="handleCheckboxInput">
+ <label for="password-checkbox">{{ t('spreed', 'Password protect') }}</label>
+ <PasswordProtect
+ v-if="passwordProtect"
+ v-model="password" />
+ </template>
</template>
<template v-if="page === 1">
<SetContacts
@@ -108,8 +120,10 @@ import { addParticipant } from '../../../services/participantsService'
import {
createPublicConversation,
createPrivateConversation,
+ setConversationPassword,
} from '../../../services/conversationsService'
import { generateUrl } from '@nextcloud/router'
+import PasswordProtect from './PasswordProtect/PasswordProtect'
export default {
@@ -124,6 +138,7 @@ export default {
SetConversationType,
Confirmation,
Popover,
+ PasswordProtect,
},
data() {
@@ -137,6 +152,8 @@ export default {
selectedParticipants: [],
success: false,
error: false,
+ password: '',
+ passwordProtect: false,
}
},
@@ -150,7 +167,7 @@ export default {
} else return ''
},
disabled() {
- return this.conversationName === ''
+ return this.conversationName === '' || (this.passwordProtect && this.password === '')
},
},
@@ -169,6 +186,7 @@ export default {
this.selectedParticipants = []
this.success = false
this.error = false
+ this.password = ''
},
handleSetConversationName(event) {
this.page = 1
@@ -199,7 +217,11 @@ export default {
if (this.isPublic) {
try {
await this.createPublicConversation()
+ if (this.password && this.passwordProtect) {
+ await setConversationPassword(this.token, this.password)
+ }
} catch (exception) {
+ console.debug(exception)
this.isLoading = false
this.error = true
// Stop the execution of the method on exceptions.
@@ -209,6 +231,7 @@ export default {
try {
await this.createPrivateConversation()
} catch (exception) {
+ console.debug(exception)
this.isLoading = false
this.error = true
// Stop the execution of the method on exceptions.
@@ -252,6 +275,13 @@ export default {
this.$router.push({ name: 'conversation', params: { token: this.token } })
.catch(err => console.debug(`Error while pushing the new conversation's route: ${err}`))
},
+ handleCheckboxInput(event) {
+ this.passwordProtect = event.target.checked
+ // Reinitialise the password value when unchecking the password-protect option.
+ if (this.passwordProtect === false) {
+ this.password = ''
+ }
+ },
},
}
diff --git a/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue b/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue
new file mode 100644
index 000000000..d6c013341
--- /dev/null
+++ b/src/components/LeftSidebar/NewGroupConversation/PasswordProtect/PasswordProtect.vue
@@ -0,0 +1,67 @@
+<!--
+ - @copyright Copyright (c) 2020 Marco Ambrosini <marcoambrosini@pm.me>
+ -
+ - @author Marco Ambrosini <marcoambrosini@pm.me>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<template>
+ <input
+ ref="password"
+ v-observe-visibility="visibilityChanged"
+ type="text"
+ :value="value"
+ class="password-protect"
+ :placeholder="t('spreed', 'Choose a password')"
+ @input="handleInput">
+</template>
+
+<script>
+
+export default {
+ name: 'PasswordProtect',
+
+ props: {
+ value: {
+ type: String,
+ required: true,
+ },
+ },
+
+ methods: {
+ handleInput(event) {
+ this.$emit('input', event.target.value)
+ },
+ visibilityChanged(isVisible) {
+ if (isVisible) {
+ // Focus the input field of the current component.
+ this.$refs.password.focus()
+ }
+ },
+ },
+
+}
+
+</script>
+
+<style lang="scss" scoped>
+
+.password-protect {
+ width: calc(100% - 18px);
+ margin-left: 18px;
+}
+</style>
diff --git a/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue b/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue
index e9cce0cd6..89ee35799 100644
--- a/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue
+++ b/src/components/LeftSidebar/NewGroupConversation/SetConversationType/SetConversationType.vue
@@ -28,9 +28,6 @@
:checked="value"
@change="handleInput">
<label for="checkbox" class="conversation-type__label">{{ t('spreed', 'Allow guests to join via link ') }}</label>
- <p class="conversation-type__hint">
- {{ t('spreed', `If checked, you will be able to share this conversation with unregistered users once the conversation is created.`) }}
- </p>
</div>
</template>
diff --git a/src/components/RightSidebar/RightSidebar.vue b/src/components/RightSidebar/RightSidebar.vue
index 10ae4d655..1c329a463 100644
--- a/src/components/RightSidebar/RightSidebar.vue
+++ b/src/components/RightSidebar/RightSidebar.vue
@@ -39,6 +39,24 @@
@change="toggleGuests">
{{ t('spreed', 'Share link') }}
</ActionCheckbox>
+ <!-- password -->
+ <ActionCheckbox
+ class="share-link-password-checkbox"
+ :checked="isPasswordProtected"
+ @check="handlePasswordEnable"
+ @uncheck="handlePasswordDisable">
+ {{ t('spreed', 'Password protection') }}
+ </ActionCheckbox>
+ <ActionInput
+ v-show="isEditingPassword"
+ class="share-link-password"
+ icon="icon-password"
+ type="password"
+ :value.sync="password"
+ autocomplete="new-password"
+ @submit="handleSetNewPassword">
+ {{ t('spreed', 'Enter a password') }}
+ </ActionInput>
<ActionText
v-if="canFullModerate"
icon="icon-lobby"
@@ -98,6 +116,7 @@ import ParticipantsTab from './Participants/ParticipantsTab'
import {
addToFavorites,
removeFromFavorites,
+ setConversationPassword,
} from '../../services/conversationsService'
import isInLobby from '../../mixins/isInLobby'
@@ -129,6 +148,10 @@ export default {
return {
contactsLoading: false,
lobbyTimerLoading: false,
+ // The conversation's password
+ password: '',
+ // Switch for the password-editing operation
+ isEditingPassword: false,
}
},
@@ -231,6 +254,9 @@ export default {
showModerationMenu() {
return this.canModerate && (this.canFullModerate || this.isSharedPublicly)
},
+ isPasswordProtected() {
+ return this.$store.getters.conversations[this.token].hasPassword
+ },
},
methods: {
@@ -279,6 +305,23 @@ export default {
this.lobbyTimerLoading = false
},
+ async handlePasswordDisable() {
+ // disable the password protection for the current conversation
+ if (this.conversation.hasPassword) {
+ await setConversationPassword(this.token, '')
+ }
+ this.password = ''
+ this.isEditingPassword = false
+ },
+ async handlePasswordEnable() {
+ this.isEditingPassword = true
+ },
+
+ async handleSetNewPassword() {
+ await setConversationPassword(this.token, this.password)
+ this.password = ''
+ this.isEditingPassword = false
+ },
},
}
</script>
diff --git a/src/services/conversationsService.js b/src/services/conversationsService.js
index c9fa47644..daf3e3ab2 100644
--- a/src/services/conversationsService.js
+++ b/src/services/conversationsService.js
@@ -129,6 +129,16 @@ const createPublicConversation = async function(conversationName) {
}
/**
+ * Set a conversation's password
+ * @param {string} token the conversation's token
+ * @param {string} password the password to be set
+ */
+const setConversationPassword = async function(token, password) {
+ const response = await axios.put(generateOcsUrl('apps/spreed/api/v1', 2) + `room/${token}/password?password=${password}`)
+ return response
+}
+
+/**
* Delete a conversation.
* @param {string} token The token of the conversation to be deleted.
*/
@@ -240,4 +250,5 @@ export {
makePublic,
makePrivate,
changeLobbyState,
+ setConversationPassword,
}
diff --git a/templates/authenticate.php b/templates/authenticate.php
index 023e62685..f62042e1b 100644
--- a/templates/authenticate.php
+++ b/templates/authenticate.php
@@ -1,8 +1,8 @@
<?php
- /** @var $_ array */
- /** @var $l \OCP\IL10N */
- style('spreed', 'authenticate');
- script('spreed', 'authenticate');
+/** @var $_ array */
+/** @var $l \OCP\IL10N */
+style('core', 'publicshareauth');
+script('core', 'publicshareauth');
?>
<form method="post">
<fieldset class="warning">
@@ -16,7 +16,7 @@
<input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>" />
<input type="password" name="password" id="password"
placeholder="<?php p($l->t('Password')); ?>" value=""
- autocomplete="off" autocapitalize="off" autocorrect="off"
+ autocomplete="new-password" autocapitalize="off" autocorrect="off"
autofocus />
<input type="submit" id="password-submit"
class="svg icon-confirm input-button-inline" value="" disabled="disabled" />