2020-04-29 10:42:35 +02:00
|
|
|
import { environment } from 'src/environments/environment'
|
2020-06-23 14:10:17 +02:00
|
|
|
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
|
|
|
|
import { ActivatedRoute } from '@angular/router'
|
|
|
|
import { AuthService, Notifier, RedirectService, UserService } from '@app/core'
|
2020-05-06 14:01:30 +02:00
|
|
|
import { HooksService } from '@app/core/plugins/hooks.service'
|
2020-08-17 11:47:04 +02:00
|
|
|
import { LOGIN_PASSWORD_VALIDATOR, LOGIN_USERNAME_VALIDATOR } from '@app/shared/form-validators/login-validators'
|
|
|
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
2021-03-24 13:32:55 +01:00
|
|
|
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance'
|
2020-12-07 16:34:07 +01:00
|
|
|
import { NgbAccordion, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
|
2020-06-23 14:10:17 +02:00
|
|
|
import { RegisteredExternalAuthConfig, ServerConfig } from '@shared/models'
|
2016-03-22 15:51:54 +01:00
|
|
|
|
|
|
|
@Component({
|
2016-06-01 20:36:27 +02:00
|
|
|
selector: 'my-login',
|
2017-12-05 16:48:26 +01:00
|
|
|
templateUrl: './login.component.html',
|
|
|
|
styleUrls: [ './login.component.scss' ]
|
2016-03-22 15:51:54 +01:00
|
|
|
})
|
|
|
|
|
2020-04-29 10:42:35 +02:00
|
|
|
export class LoginComponent extends FormReactive implements OnInit, AfterViewInit {
|
2019-07-24 16:05:59 +02:00
|
|
|
@ViewChild('forgotPasswordModal', { static: true }) forgotPasswordModal: ElementRef
|
2018-01-30 13:27:07 +01:00
|
|
|
|
2020-12-07 16:34:07 +01:00
|
|
|
accordion: NgbAccordion
|
2017-06-16 14:32:15 +02:00
|
|
|
error: string = null
|
2018-01-30 13:27:07 +01:00
|
|
|
forgotPasswordEmail = ''
|
2020-04-30 15:03:09 +02:00
|
|
|
|
2020-04-28 14:49:03 +02:00
|
|
|
isAuthenticatedWithExternalAuth = false
|
2020-04-30 15:03:09 +02:00
|
|
|
externalAuthError = false
|
2020-04-29 10:42:35 +02:00
|
|
|
externalLogins: string[] = []
|
2016-06-04 13:31:23 +02:00
|
|
|
|
2020-12-07 16:34:07 +01:00
|
|
|
instanceInformationPanels = {
|
|
|
|
terms: true,
|
|
|
|
administrators: false,
|
|
|
|
features: false,
|
|
|
|
moderation: false,
|
|
|
|
codeOfConduct: false
|
|
|
|
}
|
|
|
|
|
2018-08-09 14:55:06 +02:00
|
|
|
private openedForgotPasswordModal: NgbModalRef
|
2019-12-18 15:31:54 +01:00
|
|
|
private serverConfig: ServerConfig
|
2018-08-09 14:55:06 +02:00
|
|
|
|
2018-06-04 16:21:17 +02:00
|
|
|
constructor (
|
2018-06-05 10:58:45 +02:00
|
|
|
protected formValidatorService: FormValidatorService,
|
2019-12-18 15:31:54 +01:00
|
|
|
private route: ActivatedRoute,
|
2018-08-09 14:55:06 +02:00
|
|
|
private modalService: NgbModal,
|
2018-06-04 16:21:17 +02:00
|
|
|
private authService: AuthService,
|
|
|
|
private userService: UserService,
|
|
|
|
private redirectService: RedirectService,
|
2018-12-19 16:04:34 +01:00
|
|
|
private notifier: Notifier,
|
2020-08-12 10:40:04 +02:00
|
|
|
private hooks: HooksService
|
|
|
|
) {
|
2017-06-16 14:32:15 +02:00
|
|
|
super()
|
2016-09-09 22:16:51 +02:00
|
|
|
}
|
2016-03-22 15:51:54 +01:00
|
|
|
|
2018-03-28 18:22:59 +02:00
|
|
|
get signupAllowed () {
|
2019-12-18 15:31:54 +01:00
|
|
|
return this.serverConfig.signup.allowed === true
|
2018-03-28 18:22:59 +02:00
|
|
|
}
|
|
|
|
|
2020-12-07 16:34:07 +01:00
|
|
|
onTermsClick (event: Event, instanceInformation: HTMLElement) {
|
|
|
|
event.preventDefault()
|
|
|
|
|
|
|
|
if (this.accordion) {
|
|
|
|
this.accordion.expand('terms')
|
|
|
|
instanceInformation.scrollIntoView({ behavior: 'smooth' })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-05 15:10:45 +01:00
|
|
|
isEmailDisabled () {
|
2019-12-18 15:31:54 +01:00
|
|
|
return this.serverConfig.email.enabled === false
|
2018-12-05 15:10:45 +01:00
|
|
|
}
|
|
|
|
|
2017-06-16 14:32:15 +02:00
|
|
|
ngOnInit () {
|
2020-04-28 14:49:03 +02:00
|
|
|
const snapshot = this.route.snapshot
|
|
|
|
|
2020-12-29 15:23:03 +01:00
|
|
|
// Avoid undefined errors when accessing form error properties
|
|
|
|
this.buildForm({
|
|
|
|
username: LOGIN_USERNAME_VALIDATOR,
|
|
|
|
password: LOGIN_PASSWORD_VALIDATOR
|
|
|
|
})
|
|
|
|
|
2020-04-28 14:49:03 +02:00
|
|
|
this.serverConfig = snapshot.data.serverConfig
|
|
|
|
|
|
|
|
if (snapshot.queryParams.externalAuthToken) {
|
|
|
|
this.loadExternalAuthToken(snapshot.queryParams.username, snapshot.queryParams.externalAuthToken)
|
|
|
|
return
|
|
|
|
}
|
2019-12-18 15:31:54 +01:00
|
|
|
|
2020-04-30 15:03:09 +02:00
|
|
|
if (snapshot.queryParams.externalAuthError) {
|
|
|
|
this.externalAuthError = true
|
|
|
|
return
|
|
|
|
}
|
2020-04-29 10:42:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ngAfterViewInit () {
|
2020-05-06 14:01:30 +02:00
|
|
|
this.hooks.runAction('action:login.init', 'login')
|
2020-04-29 10:42:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getExternalLogins () {
|
|
|
|
return this.serverConfig.plugin.registeredExternalAuths
|
|
|
|
}
|
2018-09-22 14:14:32 +02:00
|
|
|
|
2020-04-29 10:42:35 +02:00
|
|
|
getAuthHref (auth: RegisteredExternalAuthConfig) {
|
|
|
|
return environment.apiUrl + `/plugins/${auth.name}/${auth.version}/auth/${auth.authName}`
|
2016-08-23 14:37:49 +02:00
|
|
|
}
|
|
|
|
|
2017-06-16 14:32:15 +02:00
|
|
|
login () {
|
|
|
|
this.error = null
|
2016-09-09 22:16:51 +02:00
|
|
|
|
2017-06-16 14:32:15 +02:00
|
|
|
const { username, password } = this.form.value
|
2016-09-09 22:16:51 +02:00
|
|
|
|
2018-03-28 18:22:59 +02:00
|
|
|
this.authService.login(username, password)
|
|
|
|
.subscribe(
|
2018-12-11 15:27:46 +01:00
|
|
|
() => this.redirectService.redirectToPreviousRoute(),
|
2016-06-04 13:31:23 +02:00
|
|
|
|
2020-04-28 14:49:03 +02:00
|
|
|
err => this.handleError(err)
|
2018-03-28 18:22:59 +02:00
|
|
|
)
|
2016-03-22 15:51:54 +01:00
|
|
|
}
|
2018-01-30 13:27:07 +01:00
|
|
|
|
|
|
|
askResetPassword () {
|
|
|
|
this.userService.askResetPassword(this.forgotPasswordEmail)
|
|
|
|
.subscribe(
|
2018-08-09 17:51:25 +02:00
|
|
|
() => {
|
2020-08-12 10:40:04 +02:00
|
|
|
const message = $localize`An email with the reset password instructions will be sent to ${this.forgotPasswordEmail}.
|
|
|
|
The link will expire within 1 hour.`
|
|
|
|
|
2018-12-19 16:04:34 +01:00
|
|
|
this.notifier.success(message)
|
2018-01-30 13:27:07 +01:00
|
|
|
this.hideForgotPasswordModal()
|
|
|
|
},
|
|
|
|
|
2018-12-19 16:04:34 +01:00
|
|
|
err => this.notifier.error(err.message)
|
2018-01-30 13:27:07 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
openForgotPasswordModal () {
|
2018-08-09 14:55:06 +02:00
|
|
|
this.openedForgotPasswordModal = this.modalService.open(this.forgotPasswordModal)
|
2018-01-30 13:27:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
hideForgotPasswordModal () {
|
2018-08-09 14:55:06 +02:00
|
|
|
this.openedForgotPasswordModal.close()
|
2018-01-30 13:27:07 +01:00
|
|
|
}
|
2020-04-28 14:49:03 +02:00
|
|
|
|
2020-12-07 16:34:07 +01:00
|
|
|
onInstanceAboutAccordionInit (instanceAboutAccordion: InstanceAboutAccordionComponent) {
|
|
|
|
this.accordion = instanceAboutAccordion.accordion
|
|
|
|
}
|
|
|
|
|
2021-07-20 13:47:49 +02:00
|
|
|
hasUsernameUppercase () {
|
|
|
|
return this.form.value['username'].match(/[A-Z]/)
|
|
|
|
}
|
|
|
|
|
2020-04-28 14:49:03 +02:00
|
|
|
private loadExternalAuthToken (username: string, token: string) {
|
|
|
|
this.isAuthenticatedWithExternalAuth = true
|
|
|
|
|
|
|
|
this.authService.login(username, null, token)
|
|
|
|
.subscribe(
|
|
|
|
() => this.redirectService.redirectToPreviousRoute(),
|
|
|
|
|
|
|
|
err => {
|
|
|
|
this.handleError(err)
|
|
|
|
this.isAuthenticatedWithExternalAuth = false
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
private handleError (err: any) {
|
2020-08-12 10:40:04 +02:00
|
|
|
if (err.message.indexOf('credentials are invalid') !== -1) this.error = $localize`Incorrect username or password.`
|
|
|
|
else if (err.message.indexOf('blocked') !== -1) this.error = $localize`Your account is blocked.`
|
2020-04-28 14:49:03 +02:00
|
|
|
else this.error = err.message
|
|
|
|
}
|
2016-03-22 15:51:54 +01:00
|
|
|
}
|