diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index db87ad6..a26fc11 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -2182,6 +2182,7 @@ sub startup { $r->get('/ajax/status/:name/:ts')->to('traveling#public_status_card'); $r->get('/p/:name')->to('traveling#public_profile'); $r->get('/p/:name/j/:id')->to('traveling#public_journey_details'); + $r->get('/.well-known/webfinger')->to('account#webfinger'); $r->post('/api/v1/import')->to('api#import_v1'); $r->post('/api/v1/travel')->to('api#travel_v1'); $r->post('/action')->to('traveling#travel_action'); diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm index 12b179b..334ec97 100644 --- a/lib/Travelynx/Controller/Account.pm +++ b/lib/Travelynx/Controller/Account.pm @@ -6,7 +6,8 @@ package Travelynx::Controller::Account; use Mojo::Base 'Mojolicious::Controller'; use Crypt::Eksblowfish::Bcrypt qw(bcrypt en_base64); -use UUID::Tiny qw(:std); +use JSON; +use UUID::Tiny qw(:std); # Internal Helpers @@ -967,4 +968,51 @@ sub json_export { ); } +sub webfinger { + my ($self) = @_; + + my $resource = $self->param('resource'); + + if ( not $resource ) { + $self->render('not_found'); + return; + } + + my $root_url = $self->url_for('/')->host; + + if ( not $root_url + or not $resource =~ m{ ^ (? [^@]+ ) [@] $root_url $ }x ) + { + $self->render('not_found'); + return; + } + + my $name = $+{name}; + my $user = $self->users->get_privacy_by_name( name => $name ); + + if ( not $user or not $user->{public_level} & 0x22 ) { + $self->render('not_found'); + } + + my $profile_url + = $self->url_for("/p/${name}")->to_abs->scheme('https')->to_string; + + $self->render( + text => JSON->new->encode( + { + subject => "acct:${resource}", + aliases => [ $profile_url, ], + links => [ + { + rel => 'http://webfinger.net/rel/profile-page', + type => 'text/html', + href => $profile_url, + }, + ], + } + ), + format => 'json', + ); +} + 1;