parent
7663cea2ea
commit
ea77402750
@ -0,0 +1,217 @@
|
||||
import { Component } from '../../../lib/vues6/vues6.js'
|
||||
import { location_service } from '../../service/Location.service.js'
|
||||
import { auth_api } from '../../service/AuthApi.service.js'
|
||||
|
||||
const template = `
|
||||
<div class="coreid-login-form col-lg-6 col-md-8 col-sm-10 col-xs-12 offset-lg-3 offset-md-2 offset-sm-1 offset-xs-0 text-left">
|
||||
<div class="coreid-login-form-inner">
|
||||
<div class="coreid-login-form-header font-weight-light">{{ app_name }}</div>
|
||||
<div class="coreid-login-form-message">{{ message }}</div>
|
||||
<form class="coreid-form" v-on:submit.prevent="do_nothing">
|
||||
<div class="form-group">
|
||||
<input
|
||||
v-if="step === 1"
|
||||
type="text"
|
||||
id="coreid-registration-form-first"
|
||||
name="first_name"
|
||||
class="form-control"
|
||||
placeholder="First Name"
|
||||
v-model="first_name"
|
||||
autofocus
|
||||
@keyup="on_key_up"
|
||||
:disabled="loading || step > 1"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
v-if="step === 1"
|
||||
type="text"
|
||||
id="coreid-registration-form-last"
|
||||
name="last_name"
|
||||
class="form-control"
|
||||
placeholder="Last Name"
|
||||
v-model="last_name"
|
||||
autofocus
|
||||
@keyup="on_key_up"
|
||||
:disabled="loading || step > 1"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
v-if="step === 2 || step === 3"
|
||||
type="text"
|
||||
id="coreid-registration-form-username"
|
||||
name="username"
|
||||
class="form-control"
|
||||
placeholder="Username"
|
||||
v-model="username"
|
||||
autofocus
|
||||
@keyup="on_key_up"
|
||||
:disabled="loading || step != 2"
|
||||
ref="input_username"
|
||||
>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input
|
||||
v-if="step === 3"
|
||||
type="email"
|
||||
id="coreid-registration-form-email"
|
||||
name="email"
|
||||
class="form-control"
|
||||
placeholder="E-Mail"
|
||||
v-model="email"
|
||||
autofocus
|
||||
@keyup="on_key_up"
|
||||
:disabled="loading || step != 3"
|
||||
ref="input_email"
|
||||
>
|
||||
</div>
|
||||
<div v-if="error_message" class="error-message">{{ error_message }}</div>
|
||||
<div v-if="other_message" class="other-message">{{ other_message }}</div>
|
||||
<div class="buttons text-right">
|
||||
<small
|
||||
class="mr-3"
|
||||
v-if="step === 1 && !loading"
|
||||
><a href="#" class="text-secondary" @click="on_login_click">Already have an account?</a></small>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
:disabled="loading"
|
||||
v-if="step > 1"
|
||||
v-on:click="back_click"
|
||||
>Back</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
:disabled="loading || btn_disabled"
|
||||
v-on:click="step_click"
|
||||
>{{ button_text }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="coreid-loading-spinner" v-if="loading"><div class="inner"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
// Required: First Name, Last Name, Username, E-Mail, Password (Confirm)
|
||||
export default class RegistrationFormComponent extends Component {
|
||||
static get selector() { return 'coreid-registration-form' }
|
||||
static get template() { return template }
|
||||
static get props() { return ['app_name'] }
|
||||
|
||||
loading = false
|
||||
step = 1
|
||||
other_message = ''
|
||||
error_message = ''
|
||||
message = ''
|
||||
btn_disabled = true
|
||||
button_text = 'Continue'
|
||||
|
||||
first_name = ''
|
||||
last_name = ''
|
||||
username = ''
|
||||
email = ''
|
||||
|
||||
async vue_on_create() {
|
||||
this.message = 'Create an account to continue:'
|
||||
}
|
||||
|
||||
async step_click() {
|
||||
this.loading = true
|
||||
this.error_message = ''
|
||||
this.other_message = ''
|
||||
if ( this.step === 1 ) {
|
||||
if ( !this.first_name.trim() || !this.last_name.trim() ) {
|
||||
this.error_message = 'Please provide your first and last name.'
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
this.message = `Hi, ${this.first_name.trim()}. Now, you need to choose a username:`
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input_username.focus()
|
||||
})
|
||||
} else if ( this.step === 2 ) {
|
||||
if ( await auth_api.username_taken(this.username) ) {
|
||||
this.error_message = 'That username is already taken.'
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
this.$nextTick(function() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input_email.focus()
|
||||
})
|
||||
})
|
||||
} else if ( this.step === 3 ) {
|
||||
if ( !(await auth_api.validate_email(this.email)) ) {
|
||||
this.error_message = 'Please provide a valid e-mail address.'
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
if ( await auth_api.email_taken(this.email) ) {
|
||||
this.error_message = 'That e-mail address is already taken.'
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await auth_api.register_user({
|
||||
first_name: this.first_name,
|
||||
last_name: this.last_name,
|
||||
uid: this.username,
|
||||
email: this.email,
|
||||
})
|
||||
|
||||
if ( !user ) this.error_message = 'Sorry, an unknown error has occurred and we are unable to continue at this time.'
|
||||
else this.other_message = 'Welcome! Let\'s get your password set up...'
|
||||
this.btn_disabled = true
|
||||
return location_service.redirect('/dash', 2000)
|
||||
} catch (e) {
|
||||
this.error_message = e.message || 'Sorry, an unknown error has occurred and we are unable to continue at this time.'
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ( this.step < 3 ) this.step += 1
|
||||
this.loading = false
|
||||
this.btn_disabled = true
|
||||
}
|
||||
|
||||
async back_click() {
|
||||
this.error_message = ''
|
||||
this.other_message = ''
|
||||
this.step -= 1
|
||||
this.on_key_up()
|
||||
|
||||
if ( this.step === 1 ) {
|
||||
this.message = 'Create an account to continue:'
|
||||
}
|
||||
}
|
||||
|
||||
on_key_up(event) {
|
||||
if ( this.step === 1 ) {
|
||||
this.btn_disabled = !(this.first_name.trim() && this.last_name.trim())
|
||||
} else if ( this.step === 2 ) {
|
||||
this.btn_disabled = !this.username.trim() || !this.username.match(/^([A-Z]|[a-z]|[0-9]|_|-|\.)+$/)
|
||||
} else if ( this.step === 3 ) {
|
||||
this.btn_disabled = !this.email.trim()
|
||||
}
|
||||
|
||||
if ( event.keyCode === 13 ) {
|
||||
// Enter was pressed
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if ( !this.btn_disabled ) return this.step_click()
|
||||
}
|
||||
}
|
||||
|
||||
on_login_click() {
|
||||
this.loading = true
|
||||
this.other_message = 'Okay! We\'ll have you login instead...'
|
||||
location_service.redirect('/auth/login', 1500)
|
||||
}
|
||||
|
||||
do_nothing() {}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
const { Middleware } = require('libflitter')
|
||||
|
||||
class TrapUtility {
|
||||
constructor(req, res, configs) {
|
||||
this.request = req
|
||||
this.response = res
|
||||
this.user = req.user
|
||||
this.configs = configs
|
||||
}
|
||||
|
||||
async begin(trap_name) {
|
||||
this.user.trap = trap_name
|
||||
this.request.trust.assume()
|
||||
await this.user.save()
|
||||
}
|
||||
|
||||
redirect() {
|
||||
this.request.trust.assume()
|
||||
return this.response.redirect(this.config().redirect_to)
|
||||
}
|
||||
|
||||
async end() {
|
||||
this.user.trap = ''
|
||||
this.request.trust.unassume()
|
||||
await this.user.save()
|
||||
}
|
||||
|
||||
has_trap() {
|
||||
return !!this.user.trap
|
||||
}
|
||||
|
||||
get_trap() {
|
||||
return this.user.trap
|
||||
}
|
||||
|
||||
config() {
|
||||
return this.configs[this.get_trap()]
|
||||
}
|
||||
|
||||
allows(route) {
|
||||
const config = this.config()
|
||||
return route.startsWith('/assets') || config.allowed_routes.includes(route.toLowerCase().trim())
|
||||
}
|
||||
}
|
||||
|
||||
class TrapsMiddleware extends Middleware {
|
||||
static get services() {
|
||||
return [...super.services, 'models', 'configs']
|
||||
}
|
||||
|
||||
async test(req, res, next, args = {}) {
|
||||
if ( !req?.user ) return next()
|
||||
req.trap = new TrapUtility(req, res, this.configs.get('traps.types'))
|
||||
|
||||
if ( !req.trap.has_trap() ) return next()
|
||||
else if ( req.trap.allows(req.path) ) return next()
|
||||
else return req.trap.redirect()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = TrapsMiddleware
|
@ -0,0 +1,19 @@
|
||||
const { Middleware, HTTPError } = require('libflitter')
|
||||
|
||||
class SettingMiddleware extends Middleware {
|
||||
static get services() {
|
||||
return [...super.services, 'models']
|
||||
}
|
||||
|
||||
async test(req, res, next, { key, value = true }) {
|
||||
const Setting = this.models.get('Setting')
|
||||
const actual_value = await Setting.get(key)
|
||||
|
||||
if ( actual_value !== value )
|
||||
throw new HTTPError(404)
|
||||
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = SettingMiddleware
|
@ -1,16 +1,7 @@
|
||||
extends ./form
|
||||
extends ../theme/public/base
|
||||
|
||||
block form
|
||||
.form-label-group
|
||||
input#inputUsername.form-control(type='text' name='username' value=(form_data ? form_data.username : '') required placeholder='Username' autofocus)
|
||||
label(for='inputUsername') Username
|
||||
.form-label-group
|
||||
input#inputPassword.form-control(type='password' name='password' required placeholder='Password')
|
||||
label(for='inputPassword') Password
|
||||
button.btn.btn-lg.btn-primary.btn-block.btn-login.text-uppercase.font-weight-bold.mb-2.form-submit-button(type='submit') Register
|
||||
.text-center
|
||||
span.small Already registered?
|
||||
a(href='./login') Log-in here.
|
||||
.text-center
|
||||
span.small(style="color: #999999;") Provider: #{provider_name}
|
||||
|
||||
block append style
|
||||
link(rel='stylesheet' href='/style-asset/form.css')
|
||||
|
||||
block vue
|
||||
coreid-registration-form(v-bind:app_name="app_name")
|
||||
|
@ -0,0 +1,15 @@
|
||||
const traps_config = {
|
||||
types: {
|
||||
password_reset: {
|
||||
redirect_to: '/password/reset',
|
||||
assume_trust: true,
|
||||
allowed_routes: [
|
||||
'/password/reset',
|
||||
'/api/v1/password/resets',
|
||||
'/auth/logout',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = exports = traps_config
|
Loading…
Reference in new issue