package YTMusicAPI::Auth::OAuth::RefreshingToken; use strict; use warnings; use parent 'YTMusicAPI::Auth::OAuth::OAuthToken'; use JSON qw(encode_json); use Path::Tiny qw(path); sub new { my ( $class, $credentials, $local_cache, $args ) = @_; my $self = $class->SUPER::new($args); $self->{credentials} = $credentials; $self->{_local_cache} = $local_cache; return $self; } sub get_attribute { my ( $self, $item ) = @_; if ( $item eq "access_token" && $self->is_expiring ) { my $fresh = $self->{credentials}->refresh_token( $self->{refresh_token} ); $self->update($fresh); $self->store_token(); } return $self->{$item}; } sub local_cache { my $self = shift; if (@_) { $self->{_local_cache} = shift; $self->store_token(); } return $self->{_local_cache}; } sub prompt_for_token { my ( $class, $credentials, $open_browser, $to_file ) = @_; $open_browser //= 0; my $code = $credentials->get_code(); my $url = "$code->{verification_url}?user_code=$code->{user_code}"; if ($open_browser) { if ( $^O eq 'MSWin32' ) { system("start $url"); } elsif ( $^O eq 'darwin' ) { system("open $url"); } elsif ( $^O eq 'linux' ) { system("xdg-open $url"); } else { warn "Unable to open url. Unsupported OS"; } } print "Go to $url, finish the login flow and press Enter when done, Ctrl-C to abort\n"; ; my $raw_token = $credentials->token_from_code( $code->{device_code} ); my $ref_token = $class->new( %$raw_token, credentials => $credentials ); $ref_token->update( $ref_token->as_dict() ); if ($to_file) { $ref_token->local_cache($to_file); } return $ref_token; } sub store_token { my ( $self, $path ) = @_; $path //= $self->local_cache(); if ($path) { path($path)->spew_utf8( encode_json( $self->as_dict() ) ); } } 1;