Current section
Files
Jump to
Current section
Files
src/stytch_client.erl
-module(stytch_client).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/stytch_client.gleam").
-export([new/2, add_basic_auth/2, parse_stytch_response/2, magic_link_login_or_create/2, magic_link_authenticate/3, passcode_login_or_create/2, passcode_authenticate/4, session_authenticate/3, session_revoke/2]).
-export_type([stytch_client/0, stytch_error/0, stytch_environment/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-opaque stytch_client() :: {stytch_client,
binary(),
binary(),
stytch_environment()}.
-type stytch_error() :: {httpc_error, gleam@httpc:http_error()} |
{decode_error, gleam@dynamic@decode:decode_error()} |
{json_error, gleam@json:decode_error()} |
{client_error, stytch_codecs:stytch_client_error()}.
-type stytch_environment() :: test | live.
-file("src/stytch_client.gleam", 42).
?DOC(
" Consturct a new StytchClient given a projcet_id and sercet.\n"
" Stytch encodes the environment in the project_id so we can connect\n"
" to the correct service when it is called\n"
).
-spec new(binary(), binary()) -> stytch_client().
new(Project_id, Secret) ->
case Project_id of
<<"project-test-"/utf8, _/binary>> ->
{stytch_client, Project_id, Secret, test};
_ ->
{stytch_client, Project_id, Secret, live}
end.
-file("src/stytch_client.gleam", 222).
-spec client_to_host(stytch_client()) -> binary().
client_to_host(Stytch_client) ->
case erlang:element(4, Stytch_client) of
test ->
<<"test.stytch.com"/utf8>>;
live ->
<<"api.stytch.com"/utf8>>
end.
-file("src/stytch_client.gleam", 230).
?DOC(false).
-spec add_basic_auth(gleam@http@request:request(FNL), stytch_client()) -> gleam@http@request:request(FNL).
add_basic_auth(Req, Stytch_client) ->
Credentials = <<<<(erlang:element(2, Stytch_client))/binary, ":"/utf8>>/binary,
(erlang:element(3, Stytch_client))/binary>>,
Encoded = gleam_stdlib:base64_encode(<<Credentials/binary>>, true),
gleam@http@request:set_header(
Req,
<<"authorization"/utf8>>,
<<"Basic "/utf8, Encoded/binary>>
).
-file("src/stytch_client.gleam", 206).
-spec make_stytch_request(
stytch_client(),
gleam@http:method(),
binary(),
gleam@json:json()
) -> gleam@http@request:request(binary()).
make_stytch_request(Client, Method, Path, Data) ->
_pipe = gleam@http@request:new(),
_pipe@1 = gleam@http@request:set_scheme(_pipe, https),
_pipe@2 = gleam@http@request:set_host(_pipe@1, client_to_host(Client)),
_pipe@3 = gleam@http@request:set_path(_pipe@2, Path),
_pipe@4 = gleam@http@request:set_method(_pipe@3, Method),
_pipe@5 = add_basic_auth(_pipe@4, Client),
_pipe@6 = gleam@http@request:set_header(
_pipe@5,
<<"Content-Type"/utf8>>,
<<"application/json"/utf8>>
),
gleam@http@request:set_body(_pipe@6, gleam@json:to_string(Data)).
-file("src/stytch_client.gleam", 253).
-spec parse_stytch_success(
gleam@http@response:response(binary()),
gleam@dynamic@decode:decoder(FNU)
) -> {ok, FNU} | {error, stytch_error()}.
parse_stytch_success(Response, Decoder) ->
_pipe = erlang:element(4, Response),
_pipe@1 = gleam@json:parse(_pipe, Decoder),
gleam@result:map_error(_pipe@1, fun(Field@0) -> {json_error, Field@0} end).
-file("src/stytch_client.gleam", 262).
-spec parse_stytch_error(gleam@http@response:response(binary())) -> {ok, any()} |
{error, stytch_error()}.
parse_stytch_error(Response) ->
_pipe = erlang:element(4, Response),
_pipe@1 = gleam@json:parse(
_pipe,
stytch_codecs:stytch_client_error_decoder()
),
_pipe@2 = gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {json_error, Field@0} end
),
gleam@result:'try'(
_pipe@2,
fun(Parse_ok) -> {error, {client_error, Parse_ok}} end
).
-file("src/stytch_client.gleam", 241).
?DOC(false).
-spec parse_stytch_response(
gleam@http@response:response(binary()),
gleam@dynamic@decode:decoder(FNP)
) -> {ok, FNP} | {error, stytch_error()}.
parse_stytch_response(Response, Success_decoder) ->
case erlang:element(2, Response) of
200 ->
parse_stytch_success(Response, Success_decoder);
_ ->
parse_stytch_error(Response)
end.
-file("src/stytch_client.gleam", 53).
?DOC(
" Send a magic link to the (typically user-provided) e-mail address.\n"
"\n"
" This works whether or not the user has previously logged in.\n"
).
-spec magic_link_login_or_create(stytch_client(), binary()) -> {ok,
stytch_codecs:login_or_create_response()} |
{error, stytch_error()}.
magic_link_login_or_create(Client, Email) ->
Data = begin
_pipe = [{<<"email"/utf8>>, gleam@json:string(Email)}],
gleam@json:object(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/magic_links/email/login_or_create"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:login_or_create_response_decoder()
)
end
).
-file("src/stytch_client.gleam", 80).
?DOC(" Authenticate a token returned from Stytch during a magic link redirect flow.\n").
-spec magic_link_authenticate(stytch_client(), binary(), integer()) -> {ok,
stytch_codecs:authenticate_response()} |
{error, stytch_error()}.
magic_link_authenticate(Client, Token, Session_duration_minutes) ->
Data = begin
_pipe = {token_authenticate_request, Token, Session_duration_minutes},
stytch_codecs:token_authenticate_request_to_json(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/magic_links/authenticate"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:authenticate_response_decoder()
)
end
).
-file("src/stytch_client.gleam", 103).
?DOC(
" Create or log in a user using passcode authentication.\n"
"\n"
" Arguably more secure than magic link auth as it avoids sending an\n"
" un-verified e-mail to the user.\n"
).
-spec passcode_login_or_create(stytch_client(), binary()) -> {ok,
stytch_codecs:login_or_create_response()} |
{error, stytch_error()}.
passcode_login_or_create(Client, Email) ->
Data = begin
_pipe = [{<<"email"/utf8>>, gleam@json:string(Email)}],
gleam@json:object(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/otps/email/login_or_create"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:login_or_create_response_decoder()
)
end
).
-file("src/stytch_client.gleam", 130).
?DOC(" Authenticate the passcode the user entered and pass it to stytch client.\n").
-spec passcode_authenticate(stytch_client(), binary(), binary(), integer()) -> {ok,
stytch_codecs:authenticate_response()} |
{error, stytch_error()}.
passcode_authenticate(Client, Code, Method_id, Session_duration_minutes) ->
Data = begin
_pipe = {passcode_authenticate_request,
Code,
Method_id,
Session_duration_minutes},
stytch_codecs:passcode_authenticate_request_to_json(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/otps/authenticate"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:authenticate_response_decoder()
)
end
).
-file("src/stytch_client.gleam", 156).
?DOC(
" Authenticate a session token previously returned from a passcode or magic\n"
" link authentication flow.\n"
).
-spec session_authenticate(stytch_client(), binary(), integer()) -> {ok,
stytch_codecs:session_authenticate_response()} |
{error, stytch_error()}.
session_authenticate(Client, Token, Session_duration_minutes) ->
Data = begin
_pipe = {session_token_authenticate_request,
Token,
Session_duration_minutes},
stytch_codecs:session_token_authenticate_request_to_json(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/sessions/authenticate"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:session_authenticate_response_decoder()
)
end
).
-file("src/stytch_client.gleam", 184).
?DOC(
" Revoke a session token so it can't be used to sign in again.\n"
"\n"
" Used for signing a user out.\n"
).
-spec session_revoke(stytch_client(), binary()) -> {ok,
stytch_codecs:session_revoke_response()} |
{error, stytch_error()}.
session_revoke(Client, Token) ->
Data = begin
_pipe = {session_revoke_request, Token},
stytch_codecs:session_revoke_request_to_json(_pipe)
end,
Request = make_stytch_request(
Client,
post,
<<"/v1/sessions/revoke"/utf8>>,
Data
),
gleam@result:'try'(
begin
_pipe@1 = gleam@httpc:send(Request),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {httpc_error, Field@0} end
)
end,
fun(Response) ->
parse_stytch_response(
Response,
stytch_codecs:session_revoke_response_decoder()
)
end
).