Current section

Files

Jump to
glitch src glitch@auth@token_fetcher.erl
Raw

src/glitch@auth@token_fetcher.erl

-module(glitch@auth@token_fetcher).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([fetch/2, new/4]).
-export_type([message/0, token_fetcher_state/0]).
-opaque message() :: {fetch,
gleam@erlang@process:subject({ok,
glitch@types@access_token:access_token()} |
{error, glitch@error:twitch_error()})}.
-opaque token_fetcher_state() :: {state,
binary(),
binary(),
gleam@option:option(gleam@uri:uri()),
list(glitch@types@scope:scope())}.
-spec fetch(
gleam@erlang@process:subject(message()),
gleam@erlang@process:subject({ok, glitch@types@access_token:access_token()} |
{error, glitch@error:twitch_error()})
) -> nil.
fetch(Token_fetcher, Reply_to) ->
gleam@otp@actor:send(Token_fetcher, {fetch, Reply_to}).
-spec new_authorization_uri(token_fetcher_state(), binary()) -> gleam@uri:uri().
new_authorization_uri(Token_fetcher, Csrf_state) ->
Scopes = begin
_pipe = erlang:element(5, Token_fetcher),
gleam@list:fold(_pipe, <<""/utf8>>, fun(Acc, Scope) -> case Acc of
<<""/utf8>> ->
glitch@types@scope:to_string(Scope);
_ ->
<<<<Acc/binary, "+"/utf8>>/binary,
(glitch@types@scope:to_string(Scope))/binary>>
end end)
end,
Redirect_uri = begin
_pipe@1 = erlang:element(4, Token_fetcher),
_pipe@2 = gleam@option:unwrap(
_pipe@1,
{uri,
{some, <<"http"/utf8>>},
none,
{some, <<"localhost"/utf8>>},
{some, 3000},
<<"redirect"/utf8>>,
none,
none}
),
gleam@uri:to_string(_pipe@2)
end,
Query_params = [{<<"client_id"/utf8>>, erlang:element(2, Token_fetcher)},
{<<"redirect_uri"/utf8>>, Redirect_uri},
{<<"response_type"/utf8>>, <<"code"/utf8>>},
{<<"scope"/utf8>>, Scopes},
{<<"state"/utf8>>, Csrf_state}],
glitch@extended@uri_ext:set_query(
{uri,
{some, <<"https"/utf8>>},
none,
{some, <<"id.twitch.tv"/utf8>>},
none,
<<"oauth2/authorize"/utf8>>,
none,
none},
Query_params
).
-spec handle_fetch(
token_fetcher_state(),
gleam@erlang@process:subject({ok, glitch@types@access_token:access_token()} |
{error, glitch@error:twitch_error()})
) -> gleam@otp@actor:next(any(), token_fetcher_state()).
handle_fetch(State, Reply_to) ->
Mailbox = gleam@erlang@process:new_subject(),
_assert_subject = begin
_pipe = prng@random:bit_array(),
_pipe@1 = prng@random:step(_pipe, prng@seed:random()),
_pipe@2 = gleam@pair:first(_pipe@1),
gleam@bit_array:to_string(_pipe@2)
end,
{ok, Csrf_state} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glitch/auth/token_fetcher"/utf8>>,
function => <<"handle_fetch"/utf8>>,
line => 121})
end,
Redirect_uri = gleam@option:unwrap(
erlang:element(4, State),
{uri,
{some, <<"http"/utf8>>},
none,
{some, <<"localhost"/utf8>>},
{some, 3000},
<<"redirect"/utf8>>,
none,
none}
),
_assert_subject@1 = glitch@auth@redirect_server:new(
Csrf_state,
Mailbox,
Redirect_uri
),
{ok, Server} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"glitch/auth/token_fetcher"/utf8>>,
function => <<"handle_fetch"/utf8>>,
line => 129})
end,
glitch@auth@redirect_server:start(Server),
Authorize_uri = begin
_pipe@3 = State,
_pipe@4 = new_authorization_uri(_pipe@3, Csrf_state),
gleam@uri:to_string(_pipe@4)
end,
_assert_subject@2 = case gleam_erlang_ffi:os_family() of
windows_nt ->
shellout:command(
<<"cmd"/utf8>>,
[<<"/c"/utf8>>,
<<"start"/utf8>>,
gleam@string:replace(
Authorize_uri,
<<"&"/utf8>>,
<<"^&"/utf8>>
)],
<<"."/utf8>>,
[]
);
_ ->
shellout:command(<<"open"/utf8>>, [Authorize_uri], <<"."/utf8>>, [])
end,
{ok, _} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"glitch/auth/token_fetcher"/utf8>>,
function => <<"handle_fetch"/utf8>>,
line => 138})
end,
Code = begin
_pipe@5 = gleam_erlang_ffi:new_selector(),
_pipe@6 = gleam@erlang@process:selecting(
_pipe@5,
Mailbox,
fun gleam@function:identity/1
),
gleam_erlang_ffi:select(_pipe@6)
end,
Request = glitch@api@auth:new_authorization_code_grant_request(
erlang:element(2, State),
erlang:element(3, State),
Code,
Redirect_uri
),
Response = begin
_pipe@7 = glitch@api@auth:get_token(Request),
gleam@result:map_error(
_pipe@7,
fun(Error) -> {auth_error, {token_fetcher_fetch_error, Error}} end
)
end,
glitch@auth@redirect_server:shutdown(Server),
gleam@otp@actor:send(Reply_to, Response),
gleam@otp@actor:continue(State).
-spec handle_message(message(), token_fetcher_state()) -> gleam@otp@actor:next(message(), token_fetcher_state()).
handle_message(Message, State) ->
case Message of
{fetch, Reply_to} ->
handle_fetch(State, Reply_to)
end.
-spec new(
binary(),
binary(),
list(glitch@types@scope:scope()),
gleam@option:option(gleam@uri:uri())
) -> {ok, gleam@erlang@process:subject(message())} |
{error, glitch@error:twitch_error()}.
new(Client_id, Client_secret, Scopes, Redirect_uri) ->
State = {state, Client_id, Client_secret, Redirect_uri, Scopes},
_pipe = gleam@otp@actor:start(State, fun handle_message/2),
gleam@result:replace_error(_pipe, {auth_error, token_fetcher_start_error}).