Adding initial login support.
This commit is contained in:
parent
61b0066f0a
commit
1447b2fa6e
1
Build.PL
1
Build.PL
@ -31,6 +31,7 @@ my $build = Module::Build->new(
|
||||
'DBIx::Class' => 0,
|
||||
'UUID::URandom' => 0,
|
||||
'Crypt::Bcrypt' => 0,
|
||||
'DBIx::Class::TimeStamp' => 0,
|
||||
},
|
||||
);
|
||||
$build->create_build_script;
|
||||
|
@ -16,6 +16,9 @@ export default class Conquer {
|
||||
private conquerLoginGoToRegister: HTMLAnchorElement
|
||||
private conquerLoginError: HTMLParagraphElement
|
||||
private conquerLoginSuccess: HTMLParagraphElement
|
||||
private conquerLoginUsername: HTMLInputElement
|
||||
private conquerLoginPassword: HTMLInputElement
|
||||
private conquerLoginSubmit: HTMLButtonElement
|
||||
private conquerRegisterGoToLogin: HTMLAnchorElement
|
||||
private conquerRegister: HTMLDivElement
|
||||
private conquerRegisterUsername: HTMLInputElement
|
||||
@ -73,7 +76,54 @@ export default class Conquer {
|
||||
Conquer.fail('Unable to find conquer login success.')
|
||||
}
|
||||
this.conquerLoginSuccess = conquerLoginSuccess
|
||||
const conquerLoginUsername = document.querySelector('.conquer-login-username')
|
||||
if (conquerLoginUsername === null || !(conquerLoginUsername instanceof HTMLInputElement)) {
|
||||
Conquer.fail('Unable to find conquer login username field.')
|
||||
}
|
||||
this.conquerLoginUsername = conquerLoginUsername
|
||||
const conquerLoginPassword = document.querySelector('.conquer-login-password')
|
||||
if (conquerLoginPassword === null || !(conquerLoginPassword instanceof HTMLInputElement)) {
|
||||
Conquer.fail('Unable to find conquer login password field.')
|
||||
}
|
||||
this.conquerLoginPassword = conquerLoginPassword
|
||||
const conquerLoginSubmit = document.querySelector('.conquer-login-submit')
|
||||
if (conquerLoginSubmit === null || !(conquerLoginSubmit instanceof HTMLButtonElement)) {
|
||||
Conquer.fail('Unable to find the submit button for the login.')
|
||||
}
|
||||
this.conquerLoginSubmit = conquerLoginSubmit
|
||||
this.conquerLoginSubmit.addEventListener('click', () => {
|
||||
this.onLoginRequested()
|
||||
});
|
||||
}
|
||||
|
||||
async onLoginRequested(): Promise<void> {
|
||||
const username = this.conquerLoginUsername.value;
|
||||
const password = this.conquerLoginPassword.value;
|
||||
const urlUser = new URL('/conquer/user/login', window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
|
||||
let responseJson
|
||||
let status
|
||||
try {
|
||||
const response = await fetch(urlUser, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
})
|
||||
})
|
||||
responseJson = await response.json()
|
||||
status = response.status
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
this.addNewLoginError('El servidor ha enviado datos inesperados.')
|
||||
return;
|
||||
}
|
||||
if (status !== 200) {
|
||||
this.addNewLoginError(responseJson.error)
|
||||
return
|
||||
}
|
||||
this.unsetLoginAndRegisterErrors()
|
||||
}
|
||||
|
||||
async goToRegister(): Promise<void> {
|
||||
const isLogged = await this.isLogged();
|
||||
await this.removeLoginRegisterCombo()
|
||||
@ -150,22 +200,25 @@ export default class Conquer {
|
||||
const password = this.conquerRegisterPassword.value
|
||||
const repeatPassword = this.conquerRegisterRepeatPassword.value
|
||||
const urlUser = new URL('/conquer/user', window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
|
||||
const response = await fetch(urlUser, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
repeat_password: repeatPassword
|
||||
})
|
||||
})
|
||||
let responseJson
|
||||
let status
|
||||
try {
|
||||
const response = await fetch(urlUser, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
repeat_password: repeatPassword
|
||||
})
|
||||
})
|
||||
responseJson = await response.json()
|
||||
status = response.status
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
this.addNewRegisterError('El servidor ha enviado datos inesperados.')
|
||||
return;
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
if (status !== 200) {
|
||||
this.addNewRegisterError(responseJson.error)
|
||||
return
|
||||
}
|
||||
@ -178,6 +231,12 @@ export default class Conquer {
|
||||
this.conquerLoginSuccess.classList.remove('conquer-display-none')
|
||||
|
||||
}
|
||||
addNewLoginError(error: string): void {
|
||||
this.unsetLoginAndRegisterErrors()
|
||||
this.conquerLoginSuccess.classList.add('conquer-display-none')
|
||||
this.conquerLoginError.innerText = error
|
||||
this.conquerLoginError.classList.remove('conquer-display-none')
|
||||
}
|
||||
addNewRegisterError(error: string): void {
|
||||
this.unsetLoginAndRegisterErrors()
|
||||
this.conquerLoginSuccess.classList.add('conquer-display-none')
|
||||
|
@ -52,6 +52,7 @@ sub startup ($self) {
|
||||
$r->get('/stats')->to('Metrics#stats');
|
||||
$r->get('/conquer')->to('Conquer#index');
|
||||
$r->put('/conquer/user')->to('UserConquer#create');
|
||||
$r->post('/conquer/user/login')->to('UserConquer#login');
|
||||
$r->get('/search.json')->to('Search#search');
|
||||
$r->get('/farmacia-guardia.json')->to('FarmaciaGuardia#current');
|
||||
$r->get('/<:category>.rss')->to('Page#category_rss');
|
||||
|
@ -89,8 +89,6 @@ sub submit_login {
|
||||
$self->render( text => 'Server error.', status => 500 );
|
||||
return;
|
||||
}
|
||||
say $password;
|
||||
say $bcrypted_pass;
|
||||
if ( !bcrypt_check( $password, $bcrypted_pass ) ) {
|
||||
$self->render( text => 'Wrong password', status => 401 );
|
||||
return;
|
||||
|
@ -12,6 +12,7 @@ use Mojo::Base 'Mojolicious::Controller', '-signatures';
|
||||
use UUID::URandom qw/create_uuid_string/;
|
||||
use Crypt::Bcrypt qw/bcrypt bcrypt_check/;
|
||||
use Crypt::URandom qw/urandom/;
|
||||
use JSON;
|
||||
|
||||
use BurguillosInfo::Schema;
|
||||
|
||||
@ -21,18 +22,56 @@ my $password_minimum_chars = 8;
|
||||
my $password_maximum_chars = 4096;
|
||||
|
||||
sub create ($self) {
|
||||
my $input;
|
||||
eval { $input = $self->req->json; };
|
||||
if ($@) {
|
||||
say STDERR $@;
|
||||
return $self->render( text => 'Expecting json', status => 400 );
|
||||
my $input = $self->_expectJson;
|
||||
if ( !defined $input ) {
|
||||
return;
|
||||
}
|
||||
my $username = $input->{username};
|
||||
my $password = $input->{password};
|
||||
my $repeat_password = $input->{repeat_password};
|
||||
return
|
||||
unless $self->_createCheckInput( $username, $password, $repeat_password );
|
||||
return $self->_createUser($username, $password);
|
||||
return $self->_createUser( $username, $password );
|
||||
}
|
||||
|
||||
sub _expectJson ($self) {
|
||||
my $input;
|
||||
eval { $input = $self->req->json; };
|
||||
if ($@) {
|
||||
say STDERR $@;
|
||||
$self->_renderError(400, 'Se esperaba JSON.');
|
||||
return;
|
||||
}
|
||||
return $input;
|
||||
}
|
||||
|
||||
sub login ($self) {
|
||||
my $input = $self->_expectJson;
|
||||
if ( !defined $input ) {
|
||||
return;
|
||||
}
|
||||
my $username = $input->{username};
|
||||
my $password = $input->{password};
|
||||
|
||||
my $resultset_conquer_user =
|
||||
BurguillosInfo::Schema->Schema->resultset('ConquerUser');
|
||||
my @tentative_users =
|
||||
$resultset_conquer_user->search( { username => $username } );
|
||||
my $tentative_user = $tentative_users[0];
|
||||
if (!defined $tentative_user) {
|
||||
$self->_renderError(401, 'El usuario especificado no existe.');
|
||||
return;
|
||||
}
|
||||
if ( !bcrypt_check( $password, $tentative_user->encrypted_password ) ) {
|
||||
$self->_renderError( 401, 'Contraseña incorrecta.' );
|
||||
return;
|
||||
}
|
||||
$self->render(
|
||||
json => {
|
||||
success => $JSON::true
|
||||
},
|
||||
status => 200
|
||||
);
|
||||
}
|
||||
|
||||
sub _createUser ( $self, $username, $password ) {
|
||||
@ -52,19 +91,19 @@ sub _createUser ( $self, $username, $password ) {
|
||||
};
|
||||
if ($@) {
|
||||
if ( $@ =~ /Key \((.*?)\)=\((.*?)\) already exists\./ ) {
|
||||
return $self->renderError( 400,
|
||||
"The key $1 ($2) already exists in the database.",
|
||||
return $self->_renderError( 400,
|
||||
"La clave $1 ($2) ya existe en la base de datos.",
|
||||
);
|
||||
}
|
||||
say STDERR $@;
|
||||
return $self->renderError( 400,
|
||||
return $self->_renderError( 400,
|
||||
'No se pudo crear el usuario por razones desconocidas.' );
|
||||
}
|
||||
$self->render(status => 200, json => $user->serialize_to_owner);
|
||||
$self->render( status => 200, json => $user->serialize_to_owner );
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub renderError ( $self, $status, $message ) {
|
||||
sub _renderError ( $self, $status, $message ) {
|
||||
$self->render( status => $status, json => { error => $message } );
|
||||
return 0;
|
||||
}
|
||||
@ -75,7 +114,7 @@ sub _createCheckInput ( $self, $username, $password, $repeat_password ) {
|
||||
/^(?:\w|\d|[ÑÁÉÍÓÚñáéíóú ]){$username_minimum_chars,$username_maximum_chars}$/
|
||||
)
|
||||
{
|
||||
return $self->renderError( 400,
|
||||
return $self->_renderError( 400,
|
||||
"Username invalido, las reglas son tamaño entre $username_minimum_chars y $username_maximum_chars"
|
||||
. ' carácteres y solo se podrán usar letras, números y espacios.'
|
||||
);
|
||||
@ -85,7 +124,7 @@ sub _createCheckInput ( $self, $username, $password, $repeat_password ) {
|
||||
|| $password !~ /^.{$password_minimum_chars,$password_maximum_chars}$/
|
||||
|| $password =~ /^\d+$/ )
|
||||
{
|
||||
return $self->renderError(
|
||||
return $self->_renderError(
|
||||
400,
|
||||
'Contraseña invalida, las reglas son la contraseña debe ser'
|
||||
. ' distinta al nombre de usuario, la contraseña debe tener entre'
|
||||
@ -96,7 +135,7 @@ sub _createCheckInput ( $self, $username, $password, $repeat_password ) {
|
||||
);
|
||||
}
|
||||
if ( !defined $repeat_password || $password ne $repeat_password ) {
|
||||
$self->renderError(
|
||||
$self->_renderError(
|
||||
400,
|
||||
'El campo de repetir contraseña debe coincidir de forma'
|
||||
. ' totalmente exacta con el campo de contraseña para asegurar'
|
||||
|
@ -53,10 +53,10 @@ sub MIGRATIONS {
|
||||
uuid UUID NOT NULL PRIMARY KEY,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
encrypted_password TEXT NOT NULL,
|
||||
last_activity TEXT NOT NULL DEFAULT NOW(),
|
||||
is_admin boolean NOT NULL DEFAULT false
|
||||
last_activity TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
is_admin BOOLEAN NOT NULL DEFAULT false,
|
||||
registration_date TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);',
|
||||
'ALTER TABLE conquer_user ADD COLUMN registration_date TIMESTAMP NOT NULL DEFAULT NOW();',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use parent 'DBIx::Class::Core';
|
||||
use feature 'signatures';
|
||||
|
||||
__PACKAGE__->table('conquer_user');
|
||||
__PACKAGE__->load_components("TimeStamp");
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
uuid => {
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user