From 9cdb045c2ad928f8ca9da842e71c84fc5d3a173f Mon Sep 17 00:00:00 2001 From: Angelina Filippova <linakirsanova@gmail.com> Date: Wed, 4 Sep 2019 22:53:38 +0300 Subject: [PATCH] Add ability to create new invite tokens --- src/api/users.js | 10 +++ src/lang/en.js | 6 +- src/store/modules/users.js | 15 +++- .../users/components/NewAccountDialog.vue | 81 ++++++++++++++----- 4 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/api/users.js b/src/api/users.js index dd75045f..7e9001b2 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -57,6 +57,16 @@ export async function fetchUsers(filters, authHost, token, page = 1) { }) } +export async function generateInviteToken(max_use, expires_at, authHost, token) { + return await request({ + baseURL: baseName(authHost), + url: `/api/pleroma/admin/users/invite_token`, + method: 'get', + headers: authHeaders(token), + invite: typeof expires_at === 'object' ? { max_use, expires_at } : { max_use } + }) +} + export async function searchUsers(query, filters, authHost, token, page = 1) { return await request({ baseURL: baseName(authHost), diff --git a/src/lang/en.js b/src/lang/en.js index e21edbce..497f27f9 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -224,7 +224,11 @@ export default { invalidEmailError: 'Please input valid e-mail', emptyPasswordError: 'Please input the password', emptyNicknameError: 'Please input the username', - invalidNicknameError: 'Username can include "a-z", "A-Z" and "0-9" characters' + invalidNicknameError: 'Username can include "a-z", "A-Z" and "0-9" characters', + maxUse: 'Max use', + expiresAt: 'Expires at', + tokenCreated: 'Invite token was created', + token: 'Token' }, userProfile: { tags: 'Tags', diff --git a/src/store/modules/users.js b/src/store/modules/users.js index 0246a98d..7af8d60a 100644 --- a/src/store/modules/users.js +++ b/src/store/modules/users.js @@ -1,4 +1,4 @@ -import { addRight, createNewAccount, fetchUsers, deleteRight, deleteUser, searchUsers, tagUser, toggleUserActivation, untagUser } from '@/api/users' +import { addRight, createNewAccount, fetchUsers, deleteRight, deleteUser, generateInviteToken, searchUsers, tagUser, toggleUserActivation, untagUser } from '@/api/users' const users = { state: { @@ -12,7 +12,8 @@ const users = { external: false, active: false, deactivated: false - } + }, + newToken: {} }, mutations: { SET_USERS: (state, users) => { @@ -37,6 +38,9 @@ const users = { SET_COUNT: (state, count) => { state.totalUsersCount = count }, + SET_NEW_TOKEN: (state, token) => { + state.newToken = token + }, SET_PAGE: (state, page) => { state.currentPage = page }, @@ -79,6 +83,13 @@ const users = { const response = await fetchUsers(filters, getters.authHost, getters.token, page) loadUsers(commit, page, response.data) }, + async GenerateInviteToken({ commit, state, getters }, { maxUse, expiresAt }) { + const response = await generateInviteToken(maxUse, expiresAt, getters.authHost, getters.token) + commit('SET_NEW_TOKEN', { token: response.data, maxUse: response.config.invite.max_use, expiresAt: response.config.invite.expires_at }) + }, + RemoveNewToken({ commit }) { + commit('SET_NEW_TOKEN', {}) + }, async RemoveTag({ commit, getters }, { users, tag }) { const nicknames = users.map(user => user.nickname) await untagUser(nicknames, [tag], getters.authHost, getters.token) diff --git a/src/views/users/components/NewAccountDialog.vue b/src/views/users/components/NewAccountDialog.vue index 8cf2a725..f829f91c 100644 --- a/src/views/users/components/NewAccountDialog.vue +++ b/src/views/users/components/NewAccountDialog.vue @@ -5,25 +5,56 @@ :title="$t('users.createAccount')" custom-class="create-user-dialog" @open="resetForm"> - <el-form ref="form" :model="form" :rules="rules" :label-width="getLabelWidth" status-icon> - <el-form-item :label="$t('users.username')" prop="nickname" class="create-account-form-item"> - <el-input v-model="form.nickname" name="nickname" autofocus/> - </el-form-item> - <el-form-item :label="$t('users.email')" prop="email" class="create-account-form-item"> - <el-input v-model="form.email" name="email" type="email"/> - </el-form-item> - <el-form-item :label="$t('users.password')" prop="password" class="create-account-form-item"> - <el-input v-model="form.password" type="password" name="password" autocomplete="off"/> - </el-form-item> - </el-form> - <span slot="footer"> - <el-button @click="closeDialogWindow">{{ $t('users.cancel') }}</el-button> - <el-button type="primary" @click="submitForm('form')">{{ $t('users.create') }}</el-button> - </span> + <el-tabs type="card"> + <el-tab-pane label="Create new user account"> + <el-form ref="newUserForm" :model="newUserForm" :rules="rules" :label-width="getLabelWidth" status-icon> + <el-form-item :label="$t('users.username')" prop="nickname" class="create-account-form-item"> + <el-input v-model="newUserForm.nickname" name="nickname" autofocus/> + </el-form-item> + <el-form-item :label="$t('users.email')" prop="email" class="create-account-form-item"> + <el-input v-model="newUserForm.email" name="email" type="email"/> + </el-form-item> + <el-form-item :label="$t('users.password')" prop="password" class="create-account-form-item"> + <el-input v-model="newUserForm.password" type="password" name="password" autocomplete="off"/> + </el-form-item> + <el-form-item> + <el-button @click="closeDialogWindow">{{ $t('users.cancel') }}</el-button> + <el-button type="primary" @click="submitForm('newUserForm')">{{ $t('users.create') }}</el-button> + </el-form-item> + </el-form> + </el-tab-pane> + <el-tab-pane label="Generate invite token"> + <el-form ref="newTokenForm" :model="newTokenForm" :rules="rules" :label-width="getLabelWidth" status-icon> + <el-form-item :label="$t('users.maxUse')" class="create-account-form-item"> + <el-input-number v-model="newTokenForm.maxUse" :min="0"/> + </el-form-item> + <el-form-item :label="$t('users.expiresAt')" class="create-account-form-item"> + <el-date-picker + v-model="newTokenForm.expiresAt" + type="date" + placeholder="Pick a date"/> + </el-form-item> + <el-form-item> + <el-button @click="closeDialogWindow">{{ $t('users.cancel') }}</el-button> + <el-button type="primary" @click="createToken">{{ $t('users.create') }}</el-button> + </el-form-item> + <el-card v-if="'token' in newToken"> + <div slot="header" class="clearfix"> + <span>{{ $t('users.tokenCreated') }}</span> + </div> + <p>{{ this.$t('users.token') }}: {{ newToken.token }}</p> + <p>{{ this.$t('users.maxUse') }}: {{ newToken.maxUse }}</p> + <p>{{ this.$t('users.expiresAt') }}: {{ expiresAt }}</p> + </el-card> + </el-form> + </el-tab-pane> + </el-tabs> </el-dialog> </template> <script> +import moment from 'moment' + export default { name: 'NewAccountDialog', props: { @@ -36,11 +67,15 @@ export default { }, data() { return { - form: { + newUserForm: { nickname: '', email: '', password: '' }, + newTokenForm: { + maxUse: 1, + expiresAt: '' + }, rules: { nickname: [ { validator: this.validateUsername, trigger: 'blur' } @@ -55,6 +90,9 @@ export default { } }, computed: { + expiresAt() { + return moment(this.newToken.expiresAt).format('MM-DD-YYYY') + }, isDesktop() { return this.$store.state.app.device === 'desktop' }, @@ -68,21 +106,28 @@ export default { }, getLabelWidth() { return this.isDesktop ? '120px' : '80px' + }, + newToken() { + return this.$store.state.users.newToken } }, methods: { closeDialogWindow() { this.$emit('closeWindow') + this.$store.dispatch('RemoveNewToken') + }, + createToken() { + this.$store.dispatch('GenerateInviteToken', this.$data.newTokenForm) }, resetForm() { this.$nextTick(() => { - this.$refs['form'].resetFields() + this.$refs['newUserForm'].resetFields() }) }, submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { - this.$emit('createNewAccount', this.$data.form) + this.$emit('createNewAccount', this.$data.newUserForm) this.closeDialogWindow() this.$message({ type: 'success', -- GitLab