76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import {LoginProvider, LoginProviderConfig} from '../LoginProvider'
|
|
import {ResponseObject, Route} from '../../../http/routing/Route'
|
|
import {view} from '../../../http/response/ViewResponseFactory'
|
|
import {Valid, Validator} from '../../../validation/Validator'
|
|
import {BasicLoginAttempt, BasicLoginAttemptType} from './BasicLoginAttempt'
|
|
import {BasicRegistrationAttempt, BasicRegistrationAttemptType} from './BasicRegistrationAttempt'
|
|
|
|
/**
|
|
* LoginProvider implementation that provides basic username/password login.
|
|
*/
|
|
export class BasicLoginProvider extends LoginProvider<LoginProviderConfig> {
|
|
public routes(): void {
|
|
super.routes()
|
|
|
|
Route.post('/login')
|
|
.alias(`@auth:${this.name}:login.submit`)
|
|
.input(Validator.fromSchema<BasicLoginAttempt>(BasicLoginAttemptType))
|
|
.handledBy((...p) => this.attemptLogin(...p))
|
|
|
|
Route.post('/register')
|
|
.alias(`@auth:${this.name}:register.submit`)
|
|
.input(Validator.fromSchema<BasicRegistrationAttempt>(BasicRegistrationAttemptType))
|
|
.handledBy((...p) => this.attemptRegistration(...p))
|
|
}
|
|
|
|
public login(): ResponseObject {
|
|
return view('@extollo:auth:login')
|
|
}
|
|
|
|
public async logout(): Promise<ResponseObject> {
|
|
await this.security.flush()
|
|
return view('@extollo:auth:logout')
|
|
}
|
|
|
|
public registration(): ResponseObject {
|
|
return view('@extollo:auth:register')
|
|
}
|
|
|
|
/** Attempt to authenticate the user with a username/password. */
|
|
public async attemptLogin(attempt: Valid<BasicLoginAttempt>): Promise<ResponseObject> {
|
|
const user = await this.security.repository.getByIdentifier(attempt.username)
|
|
if ( !user ) {
|
|
throw new Error('TODO')
|
|
}
|
|
|
|
if ( !(await user.validateCredential(attempt.password)) ) {
|
|
throw new Error('TODO')
|
|
}
|
|
|
|
await this.security.authenticate(user)
|
|
return this.redirectToIntendedRoute()
|
|
}
|
|
|
|
/** Attempt to register the user with a username/password. */
|
|
public async attemptRegistration(attempt: Valid<BasicRegistrationAttempt>): Promise<ResponseObject> {
|
|
const existingUser = await this.security.repository.getByIdentifier(attempt.username)
|
|
if ( existingUser ) {
|
|
throw new Error('TODO')
|
|
}
|
|
|
|
if ( attempt.password !== attempt.passwordConfirmation ) {
|
|
throw new Error('TODO')
|
|
}
|
|
|
|
const user = await this.security.repository.createFromCredentials(attempt.username, attempt.password)
|
|
;(user as any).firstName = attempt.firstName
|
|
;(user as any).lastName = attempt.lastName
|
|
if ( typeof (user as any).save === 'function' ) {
|
|
await (user as any).save()
|
|
}
|
|
|
|
await this.security.authenticate(user)
|
|
return this.redirectToIntendedRoute()
|
|
}
|
|
}
|