-module(foodog_ver).
-export([exp/1, iss/2, key/2, fields/1]).
-spec fields(binary()) -> {ok, map()} | {error, any()}.
fields(Token) ->
try jose_jwt:peek_payload(Token) of
Result ->
case Result of
{jose_jwt, Payload} ->
{ok, Payload};
_ ->
{error, invalid_jwt_format}
end
catch
_:_ ->
{error, decoding_error}
end.
-spec key(binary(), binary()) -> {ok, map()} | {error, any()}.
key(Token, Key) ->
try jose_jwt:verify_strict(
foodog_util:binary_to_key(Key), [<<"HS256">>], Token)
of
Jwt ->
case Jwt of
{true, {jose_jwt, Fields}, _} ->
{ok, Fields};
_ ->
{error, verification_failed}
end
catch
_:_ ->
{error, decoding_error}
end.
-spec exp(map()) -> {ok, map()} | {error, token_expired}.
exp(#{<<"exp">> := ExpTime} = Payload) ->
Now = erlang:system_time(second),
case Now < ExpTime of
true ->
{ok, Payload};
false ->
{error, token_expired}
end;
exp(Payload) ->
{ok, Payload}.
-spec iss(map(), binary()) -> {ok, map()} | {error, invalid_issuer}.
iss(#{<<"iss">> := IssuerA} = Payload, IssuerB) ->
case IssuerA == IssuerB of
false ->
{error, invalid_issuer};
true ->
{ok, Payload}
end;
iss(Payload, _IssuerB) ->
{ok, Payload}.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
fields_test() ->
Payload = #{<<"foobar">> => <<"barfoo">>},
{ok, Token} = foodog_gen:token(Payload, <<"12345">>),
{ok, Fields} = fields(Token),
?assertEqual(Payload, Fields).
iss_test() ->
Payload = #{<<"foobar">> => <<"barfoo">>, <<"iss">> => <<"example.com">>},
?assertEqual({ok, Payload}, iss(Payload, <<"example.com">>)),
?assertEqual({error, invalid_issuer}, iss(Payload, <<"example2.com">>)).
-endif.