Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/src/components/login/LoginForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export default {
.login-form {
text-align: start;
font-size: 1rem;
margin: 0;

&__fieldset {
width: 100%;
Expand Down
82 changes: 40 additions & 42 deletions core/src/components/login/PasswordLessLoginForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,40 @@
<template>
<form v-if="(isHttps || isLocalhost) && supportsWebauthn"
ref="loginForm"
class="password-less-login-form"
method="post"
name="login"
@submit.prevent="submit">
<h2>{{ t('core', 'Log in with a device') }}</h2>
<fieldset>
<NcTextField required
:value="user"
:autocomplete="autoCompleteAllowed ? 'on' : 'off'"
:error="!validCredentials"
:label="t('core', 'Login or email')"
:placeholder="t('core', 'Login or email')"
:helper-text="!validCredentials ? t('core', 'Your account is not setup for passwordless login.') : ''"
@update:value="changeUsername" />
<NcTextField required
:value="user"
:autocomplete="autoCompleteAllowed ? 'on' : 'off'"
:error="!validCredentials"
:label="t('core', 'Login or email')"
:placeholder="t('core', 'Login or email')"
:helper-text="!validCredentials ? t('core', 'Your account is not setup for passwordless login.') : ''"
@update:value="changeUsername" />

<LoginButton v-if="validCredentials"
:loading="loading"
@click="authenticate" />
</fieldset>
<LoginButton v-if="validCredentials"
:loading="loading"
@click="authenticate" />
</form>
<div v-else-if="!supportsWebauthn" class="update">
<InformationIcon size="70" />
<h2>{{ t('core', 'Browser not supported') }}</h2>
<p class="infogroup">
{{ t('core', 'Passwordless authentication is not supported in your browser.') }}
</p>
</div>
<div v-else-if="!isHttps && !isLocalhost" class="update">
<LockOpenIcon size="70" />
<h2>{{ t('core', 'Your connection is not secure') }}</h2>
<p class="infogroup">
{{ t('core', 'Passwordless authentication is only available over a secure connection.') }}
</p>
</div>

<NcEmptyContent v-else-if="!isHttps && !isLocalhost"
:name="t('core', 'Your connection is not secure')"
:description="t('core', 'Passwordless authentication is only available over a secure connection.')">
<template #icon>
<LockOpenIcon />
</template>
</NcEmptyContent>

<NcEmptyContent v-else
:name="t('core', 'Browser not supported')"
:description="t('core', 'Passwordless authentication is not supported in your browser.')">
<template #icon>
<InformationIcon />
</template>
</NcEmptyContent>
</template>

<script>
Expand All @@ -46,10 +47,13 @@ import {
startAuthentication,
finishAuthentication,
} from '../../services/WebAuthnAuthenticationService.ts'
import LoginButton from './LoginButton.vue'

import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
import NcTextField from '@nextcloud/vue/components/NcTextField'

import InformationIcon from 'vue-material-design-icons/Information.vue'
import LoginButton from './LoginButton.vue'
import LockOpenIcon from 'vue-material-design-icons/LockOpen.vue'
import NcTextField from '@nextcloud/vue/components/NcTextField'
import logger from '../../logger'

export default {
Expand All @@ -58,6 +62,7 @@ export default {
LoginButton,
InformationIcon,
LockOpenIcon,
NcEmptyContent,
NcTextField,
},
props: {
Expand Down Expand Up @@ -142,17 +147,10 @@ export default {
</script>

<style lang="scss" scoped>
fieldset {
display: flex;
flex-direction: column;
gap: 0.5rem;

:deep(label) {
text-align: initial;
}
}

.update {
margin: 0 auto;
}
.password-less-login-form {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin: 0;
}
</style>
145 changes: 67 additions & 78 deletions core/src/components/login/ResetPassword.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,65 @@
-->

<template>
<form class="login-form" @submit.prevent="submit">
<fieldset class="login-form__fieldset">
<NcTextField id="user"
:value.sync="user"
name="user"
:maxlength="255"
autocapitalize="off"
:label="t('core', 'Login or email')"
:error="userNameInputLengthIs255"
:helper-text="userInputHelperText"
required
@change="updateUsername" />
<LoginButton :value="t('core', 'Reset password')" />

<NcNoteCard v-if="message === 'send-success'"
type="success">
{{ t('core', 'If this account exists, a password reset message has been sent to its email address. If you do not receive it, verify your email address and/or Login, check your spam/junk folders or ask your local administration for help.') }}
</NcNoteCard>
<NcNoteCard v-else-if="message === 'send-error'"
type="error">
{{ t('core', 'Couldn\'t send reset email. Please contact your administrator.') }}
</NcNoteCard>
<NcNoteCard v-else-if="message === 'reset-error'"
type="error">
{{ t('core', 'Password cannot be changed. Please contact your administrator.') }}
</NcNoteCard>

<a class="login-form__link"
href="#"
@click.prevent="$emit('abort')">
{{ t('core', 'Back to login') }}
</a>
</fieldset>
<form class="reset-password-form" @submit.prevent="submit">
<h2>{{ t('core', 'Reset password') }}</h2>

<NcTextField id="user"
:value.sync="user"
name="user"
:maxlength="255"
autocapitalize="off"
:label="t('core', 'Login or email')"
:error="userNameInputLengthIs255"
:helper-text="userInputHelperText"
required
@change="updateUsername" />

<LoginButton :loading="loading" :value="t('core', 'Reset password')" />

<NcButton type="tertiary" wide @click="$emit('abort')">
{{ t('core', 'Back to login') }}
</NcButton>

<NcNoteCard v-if="message === 'send-success'"
type="success">
{{ t('core', 'If this account exists, a password reset message has been sent to its email address. If you do not receive it, verify your email address and/or Login, check your spam/junk folders or ask your local administration for help.') }}
</NcNoteCard>
<NcNoteCard v-else-if="message === 'send-error'"
type="error">
{{ t('core', 'Couldn\'t send reset email. Please contact your administrator.') }}
</NcNoteCard>
<NcNoteCard v-else-if="message === 'reset-error'"
type="error">
{{ t('core', 'Password cannot be changed. Please contact your administrator.') }}
</NcNoteCard>
</form>
</template>

<script>
import axios from '@nextcloud/axios'
<script lang="ts">
import { generateUrl } from '@nextcloud/router'
import LoginButton from './LoginButton.vue'
import { defineComponent } from 'vue'

import axios from '@nextcloud/axios'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcTextField from '@nextcloud/vue/components/NcTextField'
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'

import AuthMixin from '../../mixins/auth.js'
import LoginButton from './LoginButton.vue'
import logger from '../../logger.js'

export default {
export default defineComponent({
name: 'ResetPassword',
components: {
LoginButton,
NcButton,
NcNoteCard,
NcTextField,
},

mixins: [AuthMixin],

props: {
username: {
type: String,
Expand All @@ -67,11 +73,12 @@ export default {
required: true,
},
},

data() {
return {
error: false,
loading: false,
message: undefined,
message: '',
user: this.username,
}
},
Expand All @@ -84,56 +91,38 @@ export default {
updateUsername() {
this.$emit('update:username', this.user)
},
submit() {

async submit() {
this.loading = true
this.error = false
this.message = ''
const url = generateUrl('/lostpassword/email')

const data = {
user: this.user,
}
try {
const { data } = await axios.post(url, { user: this.user })
if (data.status !== 'success') {
throw new Error(`got status ${data.status}`)
}

this.message = 'send-success'
} catch (error) {
logger.error('could not send reset email request', { error })

return axios.post(url, data)
.then(resp => resp.data)
.then(data => {
if (data.status !== 'success') {
throw new Error(`got status ${data.status}`)
}

this.message = 'send-success'
})
.catch(e => {
console.error('could not send reset email request', e)

this.error = true
this.message = 'send-error'
})
.then(() => { this.loading = false })
this.error = true
this.message = 'send-error'
} finally {
this.loading = false
}
},
},
}
})
</script>

<style lang="scss" scoped>
.login-form {
text-align: start;
font-size: 1rem;

&__fieldset {
width: 100%;
display: flex;
flex-direction: column;
gap: .5rem;
}

&__link {
display: block;
font-weight: normal !important;
cursor: pointer;
font-size: var(--default-font-size);
text-align: center;
padding: .5rem 1rem 1rem 1rem;
}
.reset-password-form {
display: flex;
flex-direction: column;
gap: .5rem;
width: 100%;
}
</style>
Loading
Loading