Packages

👯 Gleam shared library by @gleam-br

Current section

Files

Jump to
gbr_shared src gbr@shared@jwt.erl
Raw

src/gbr@shared@jwt.erl

-module(gbr@shared@jwt).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src\\gbr\\shared\\jwt.gleam").
-export([to_string/1, get_payload_claim/3, get_issuer/1, get_subject/1, get_audience/1, get_jwt_id/1, get_issued_at/1, get_not_before/1, get_expiration/1, error/1, from_string/1]).
-export_type([jwt/0, jwt_decode_error/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.
?MODULEDOC(
"\n"
" Jwt read only functions.\n"
"\n"
).
-opaque jwt() :: {jwt,
binary(),
gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@dict:dict(binary(), gleam@dynamic:dynamic_())}.
-type jwt_decode_error() :: token_empty |
header_empty |
header_invalid |
payload_empty |
payload_invalid |
claim_empty |
{claim_invalid, list(gleam@dynamic@decode:decode_error())}.
-file("src\\gbr\\shared\\jwt.gleam", 49).
?DOC(" To string encoded jwt\n").
-spec to_string(jwt()) -> binary().
to_string(In) ->
erlang:element(2, In).
-file("src\\gbr\\shared\\jwt.gleam", 97).
?DOC(" Retrieve and decode a claim from a JWT's payload.\n").
-spec get_payload_claim(jwt(), binary(), gleam@dynamic@decode:decoder(FMZ)) -> {ok,
FMZ} |
{error, jwt_decode_error()}.
get_payload_claim(Jwt, Claim, Decoder) ->
gleam@result:'try'(
begin
_pipe = erlang:element(4, Jwt),
_pipe@1 = gleam_stdlib:map_get(_pipe, Claim),
gleam@result:replace_error(_pipe@1, claim_empty)
end,
fun(Claim_value) ->
_pipe@2 = gleam@dynamic@decode:run(Claim_value, Decoder),
gleam@result:map_error(_pipe@2, fun(E) -> {claim_invalid, E} end)
end
).
-file("src\\gbr\\shared\\jwt.gleam", 55).
?DOC(" Retrieve the iss from the JWT's payload.\n").
-spec get_issuer(jwt()) -> {ok, binary()} | {error, jwt_decode_error()}.
get_issuer(Jwt) ->
get_payload_claim(
Jwt,
<<"iss"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 61).
?DOC(" Retrieve the sub from the JWT's payload.\n").
-spec get_subject(jwt()) -> {ok, binary()} | {error, jwt_decode_error()}.
get_subject(Jwt) ->
get_payload_claim(
Jwt,
<<"sub"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 67).
?DOC(" Retrieve the aud from the JWT's payload.\n").
-spec get_audience(jwt()) -> {ok, binary()} | {error, jwt_decode_error()}.
get_audience(Jwt) ->
get_payload_claim(
Jwt,
<<"aud"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 73).
?DOC(" Retrieve the jti from the JWT's payload.\n").
-spec get_jwt_id(jwt()) -> {ok, binary()} | {error, jwt_decode_error()}.
get_jwt_id(Jwt) ->
get_payload_claim(
Jwt,
<<"jti"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 79).
?DOC(" Retrieve the iat from the JWT's payload.\n").
-spec get_issued_at(jwt()) -> {ok, integer()} | {error, jwt_decode_error()}.
get_issued_at(Jwt) ->
get_payload_claim(
Jwt,
<<"iat"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 85).
?DOC(" Retrieve the nbf from the JWT's payload.\n").
-spec get_not_before(jwt()) -> {ok, integer()} | {error, jwt_decode_error()}.
get_not_before(Jwt) ->
get_payload_claim(
Jwt,
<<"nbf"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 91).
?DOC(" Retrieve the exp from the JWT's payload.\n").
-spec get_expiration(jwt()) -> {ok, integer()} | {error, jwt_decode_error()}.
get_expiration(Jwt) ->
get_payload_claim(
Jwt,
<<"exp"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1}
).
-file("src\\gbr\\shared\\jwt.gleam", 112).
-spec error(jwt_decode_error()) -> binary().
error(Err) ->
case Err of
token_empty ->
<<"Token string is empty or null"/utf8>>;
header_empty ->
<<"Header is empty or null"/utf8>>;
header_invalid ->
<<"Header is invalid"/utf8>>;
payload_empty ->
<<"Payload is empty or null"/utf8>>;
payload_invalid ->
<<"Payload is invalid"/utf8>>;
claim_empty ->
<<"Claim is empty or null"/utf8>>;
{claim_invalid, List_dec_error} ->
Dec_errors = gleam@list:map(
List_dec_error,
fun(Dec_error) ->
<<<<<<"Expected: "/utf8,
(erlang:element(2, Dec_error))/binary>>/binary,
"Found: "/utf8>>/binary,
(erlang:element(3, Dec_error))/binary>>
end
),
<<"Claim is invalid: "/utf8,
(gleam@string:join(Dec_errors, <<"\n"/utf8>>))/binary>>
end.
-file("src\\gbr\\shared\\jwt.gleam", 133).
-spec parts(binary()) -> {ok,
{gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@dict:dict(binary(), gleam@dynamic:dynamic_()),
gleam@option:option(binary())}} |
{error, jwt_decode_error()}.
parts(Jwt_string) ->
Parts = gleam@string:split(Jwt_string, <<"."/utf8>>),
gleam@result:'try'(
begin
_pipe = gleam@list:first(Parts),
gleam@result:replace_error(_pipe, header_empty)
end,
fun(Encoded_header) ->
Parts@1 = gleam@list:drop(Parts, 1),
gleam@result:'try'(
begin
_pipe@1 = Encoded_header,
_pipe@2 = gleam@bit_array:base64_url_decode(_pipe@1),
_pipe@3 = gleam@result:'try'(
_pipe@2,
fun gleam@bit_array:to_string/1
),
gleam@result:replace_error(_pipe@3, header_invalid)
end,
fun(Header_string) ->
gleam@result:'try'(
begin
_pipe@4 = gleam@json:parse(
Header_string,
gleam@dynamic@decode:dict(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
{decoder,
fun gleam@dynamic@decode:decode_dynamic/1}
)
),
gleam@result:replace_error(_pipe@4, header_invalid)
end,
fun(Header) ->
gleam@result:'try'(
begin
_pipe@5 = gleam@list:first(Parts@1),
gleam@result:replace_error(
_pipe@5,
payload_empty
)
end,
fun(Encoded_payload) ->
Parts@2 = gleam@list:drop(Parts@1, 1),
gleam@result:'try'(
begin
_pipe@6 = Encoded_payload,
_pipe@7 = gleam@bit_array:base64_url_decode(
_pipe@6
),
_pipe@8 = gleam@result:'try'(
_pipe@7,
fun gleam@bit_array:to_string/1
),
gleam@result:replace_error(
_pipe@8,
payload_invalid
)
end,
fun(Payload_string) ->
gleam@result:map(
begin
_pipe@9 = gleam@json:parse(
Payload_string,
gleam@dynamic@decode:dict(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
{decoder,
fun gleam@dynamic@decode:decode_dynamic/1}
)
),
gleam@result:replace_error(
_pipe@9,
payload_invalid
)
end,
fun(Payload) ->
Signature = begin
_pipe@10 = Parts@2,
_pipe@11 = gleam@list:first(
_pipe@10
),
gleam@option:from_result(
_pipe@11
)
end,
{Header, Payload, Signature}
end
)
end
)
end
)
end
)
end
)
end
).
-file("src\\gbr\\shared\\jwt.gleam", 39).
?DOC(" From string encoded jwt\n").
-spec from_string(binary()) -> {ok, jwt()} | {error, jwt_decode_error()}.
from_string(Raw) ->
gleam@bool:guard(
gleam@string:is_empty(Raw),
{error, token_empty},
fun() ->
gleam@result:map(
parts(Raw),
fun(_use0) ->
{Header, Payload, _} = _use0,
{jwt, Raw, Header, Payload}
end
)
end
).