diff --git a/lib/Pear/LocalLoop/Controller/Api/Devices.pm b/lib/Pear/LocalLoop/Controller/Api/Devices.pm new file mode 100644 index 0000000..c8fcf4c --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/Devices.pm @@ -0,0 +1,130 @@ +package Pear::LocalLoop::Controller::Api::Devices; +use Mojo::Base 'Mojolicious::Controller'; +use LWP::UserAgent; +use JSON; +use Mojo::File; + +has error_messages => sub { + return { + token => { + required => { message => 'Token is required', status => 400 }, + not_in_resultset => { message => 'Token already in database', status => 400 }, + }, + email => { + required => { message => 'User email is required', status => 400 }, + in_resultset => { message => 'User email not recognised', status => 400 }, + }, + }; +}; + +sub check_token { + my $c = shift; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + + $validation->required('token'); + + my $token = $validation->param('token'); + my $token_rs = $c->schema->resultset('DeviceToken')->search({'token' => $token}); + + if ($token_rs->count > 0) { + return $c->render( json => { + exists => Mojo::JSON->true + }); + } else { + return $c->render( json => { + exists => Mojo::JSON->false + }); + } +} + +sub add_token { + my $c = shift; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + + my $token_rs = $c->schema->resultset('DeviceToken'); + my $user_rs = $c->schema->resultset('User'); + + # TODO: validate that prexisting tokens are connected to the logged-in user + $validation->required('email')->in_resultset( 'email', $user_rs ); + $validation->required('token')->not_in_resultset( 'token', $token_rs ); + + return $c->api_validation_error if $validation->has_error; + + my $user = $user_rs->find({'email' => $validation->param('email')}); + + my $token = $validation->param('token'); + + $user->create_related( + 'device_tokens', + { + token => $token, + } + ); + + my $end_point = "https://iid.googleapis.com/iid/v1/${token}/rel/topics/default"; + + my $path = './localspend-47012.json'; + my $json = decode_json(Mojo::File->new($path)->slurp); + croak("No Private key in $path") if not defined $json->{server_key}; + croak("Not a service account") if $json->{type} ne 'service_account'; + + my $ua = LWP::UserAgent->new(); + my $request = HTTP::Request->new('POST', $end_point); + + $request->header('Authorization' => 'key='.$json->{server_key}); + $request->header('Content-Length' => '0'); + my $response = $ua->request($request); + + if ($response->is_success) { + my $deviceToken = $c->schema->resultset('DeviceToken')->find({'token' => $token}); + my $topic = $c->schema->resultset('Topic')->find({'name' => 'default'}); + + $deviceToken->create_related( + 'device_subscriptions', + { + topic => $topic + } + ); + + return $c->render( json => { + success => Mojo::JSON->true, + message => 'Device registered successfully!', + }); + } elsif ($response->is_error) { + return $c->render( + json => { + success => Mojo::JSON->false, + message => [ + $response->decoded_content, + ], + error => 'subscription_error', + }, + status => $response->code, + ); + } +} + +sub get_tokens { + my $c = shift; + + my $token_rs = $c->schema->resultset('DeviceToken'); + + my @tokens = ( + map {{ + id => $_->id, + user => $c->schema->resultset('User')->find({'id' => $_->user_id})->entity->customer->display_name, + token => $_->token, + }} $token_rs->all + ); + + return $c->render( json => { + success => Mojo::JSON->true, + tokens => \@tokens, + }); +} + +1;