From 28e9f205f6d394acd35b178733cc98d50e940b8c Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Wed, 6 May 2020 08:22:35 +0200 Subject: [PATCH 1/6] WIP add apns4erl & prep for iOS13 push reqs --- apps/roster/src/api/push/ios13.erl | 174 +++++++++++++++++++++++ apps/roster/src/api/push/push_api.erl | 31 +++- apps/roster/src/protocol/roster_push.erl | 29 ++-- apps/roster/src/roster.app.src | 2 +- rebar.config | 5 +- rebar.lock | 8 ++ sys.config | 1 + 7 files changed, 231 insertions(+), 19 deletions(-) create mode 100644 apps/roster/src/api/push/ios13.erl diff --git a/apps/roster/src/api/push/ios13.erl b/apps/roster/src/api/push/ios13.erl new file mode 100644 index 000000000..1a2a927ec --- /dev/null +++ b/apps/roster/src/api/push/ios13.erl @@ -0,0 +1,174 @@ +-module(ios13). +-include_lib("kernel/include/logger.hrl"). +-include("roster.hrl"). +-include_lib("roster/include/static/push_notification_var.hrl"). + +-export([start/0]). +-export([description/0, notify/6, test_push_notification/0]). + +description() -> "iOS 13.x Push Notifications Module". + +-define(APNS_CERT_DIR, proplists:get_value(apns_cert_dir, + push_api_opts(), + default_cert_dir())). + +-define(APNS_PORT, proplists:get_value(apns_port, push_api_opts(), 443)). + +-define(GATEWAY_LIST, [ + {<<"SANDBOX">>, "api.sandbox.push.apple.com"}, + {<<"LIVE">>, "api.push.apple.com"}]). + +-define(BANDLE_LIST, [ + {<<"com.nynja.mobile.communicator">>, {"cert_prod.pem", "key_prod.pem"}}, + {<<"com.nynja.rс.mobile.communicator">>, {"cert_prod.pem", "key_prod.pem"}}, + {<<"com.nynja.dev.mobile.communicator">>, {"cert_dev.pem", "key_dev.pem"}} + ]). + +start() -> + dbg:tracer(), + dbg:tpl(?MODULE, x), + dbg:tp(apns, x), + dbg:tp(gun, x), + dbg:tp(gen_tcp,connect,x), + dbg:p(all,[c]), + try start(detect_context()) + after + timer:sleep(1000), + dbg:ctpl('_'), + dbg:ctp('_'), + dbg:stop() + end. + +start(Context) -> + Conn = #{ name => ios13 + , apple_host => get_host(Context) + , apple_port => ?APNS_PORT + , certfile => certfile(Context) + , keyfile => keyfile(Context) + , type => cert }, + apns:connect(Conn). + +detect_context() -> + proplists:get_value(context, push_api_opts(), dev). + +get_host(Context) -> + Key = case Context of + dev -> + <<"SANDBOX">>; + prod -> + <<"LIVE">> + end, + proplists:get_value(Key, ?GATEWAY_LIST). + +push_api_opts() -> + application:get_env(roster, push_api, []). + +certfile(Context) -> + Base = case Context of + dev -> "cert_dev.pem"; + prod -> "cert_prod.pem"; + rc -> "cert_rc.pem" + end, + filename:join(?APNS_CERT_DIR, Base). + +keyfile(Context) -> + Base = case Context of + dev -> "key_dev.pem"; + prod -> "key_prod.pem"; + rc -> "key_rc.pem" + end, + filename:join(?APNS_CERT_DIR, Base). + +default_cert_dir() -> + filename:join(code:priv_dir(roster), "apns_certificates"). + +%% ------------------------------------------------------------------ +%% Ios Push Notifications +%% ------------------------------------------------------------------ + +notify(Alert, Custom, Type, DeviceId, SessionSettings, ConnSettings) + when is_binary(DeviceId) -> + notify(Alert, Custom, Type, binary_to_list(DeviceId), SessionSettings, ConnSettings); +notify(A, C, T, DeviceId, SessionSettings, ConnSettings) -> + [Alert, Custom, Type] = [iolist_to_binary([L]) || L <- [A, C, T]], + + Aps = #{ nynja => #{ model => Custom + , type => Type + , title => Alert + , dns => get_data_from_feature(SessionSettings, ?FKPN_SERVER_DNS) + , version => <> } }, + + %% Use DeviceId or FormattedDeviceId?? + %% FormattedDeviceId = list_to_integer(DeviceId, 16), + send_push(DeviceId, #{aps => Aps}, ConnSettings), + ok. + +%% ------------------------------------------------------------------ +%% Helpers +%% ------------------------------------------------------------------ + +send_push(DeviceId, Msg, Pid) when is_pid(Pid) -> + apns:push_notification(Pid, DeviceId, Msg). + +get_data_from_feature(SessionSettings, Key) -> + case lists:keyfind(Key, #'Feature'.key, SessionSettings) of + #'Feature'{value = Value} -> Value; + _ -> [] + end. + +%% get_bandle(SessionSettings) -> +%% [H|_]=get_from_session(SessionSettings, ?FKPN_BANDLE, ?BANDLE_LIST), +%% H. + +%% get_from_session(SessionSettings, Key, AcceptedValues) -> +%% case get_data_from_feature(SessionSettings, Key) of +%% [] -> +%% AcceptedValues; +%% FoundValue -> +%% Filtered = lists:filter( +%% fun(X) -> +%% element(1,X) == FoundValue +%% end, AcceptedValues), +%% case Filtered of +%% [] -> +%% AcceptedValues; +%% _ -> +%% Filtered +%% end +%% end. + +%% ------------------------------------------------------------------ +%% Tests +%% ------------------------------------------------------------------ + +%% Liubov's phone +-define(APNS_TEST_DEVICE_ID, "f9e7bedd8d46079c51a5aee1f951bbafc68ec541d68a56a0aa709214263cf138"). +%% Anton's phone dev +%% -define(APNS_TEST_DEVICE_ID, "55e9a60ffde1701ba701ea653ba6c0dfa4e515de7d56aa2039d72a904f353e54"). +%% Anton's phone rc +%% -define(APNS_TEST_DEVICE_ID, "a34830e7199ff499e986d2bc3ab0555b0acebe499f9a9f0445701b7dbe2a6722"). + +%% TODO: run tests +test_push_notification() -> + {ok, Pid} = start(dev), + SessionSettings = + [ + #'Feature'{ id = <<"ID_Sandbox">> + , key = <<"APNS_GATEWAY">> + , value = <<"SANDBOX">> + , group = <<"AUTH_DATA">>} + , #'Feature'{ id = <<"ID_Dns">> + , key = <<"SERVER_DNS">> + , value = <<"SomeDNSValue">> + , group = <<"AUTH_DATA">>} + , #'Feature'{ id = <<"ID_Bandle">> + , key = <<"IOS_BANDLE">> + , value = <<"com.nynja.mobile.communicator">> + , group = <<"AUTH_DATA">>} + ], + Msg = lists:concat(["Test it! ", vox_api:generate_random_data(4)]), + Custom = <<"g2gSZAAHTWVzc2FnZWEQZAAFY2hhaW5oA2QAA3AycG0AAAAOMzgw" + "NjM4MDk1MTU4XzdtAAAADjM4MDk5NDM4Mjc5OF84ampqam0AAAAO" + "MzgwOTk0MzgyNzk4XzhtAAAADjM4MDYzODA5NTE1OF83am4GAD5B" + "RlNeAWpqbAAAAAFoBmQABERlc2NqbQAAAARIaGhoYQBqampqamQABHNlbnQ=">>, + notify(Msg, Custom, <<"message">>, ?APNS_TEST_DEVICE_ID, SessionSettings, Pid). diff --git a/apps/roster/src/api/push/push_api.erl b/apps/roster/src/api/push/push_api.erl index 41990451b..a0d3862c9 100644 --- a/apps/roster/src/api/push/push_api.erl +++ b/apps/roster/src/api/push/push_api.erl @@ -1,14 +1,37 @@ -module(push_api). --export([description/0, fcm_notify/3, apns_notify/5]). +-export([start/0]). +-export([description/0, fcm_notify/4, apns_notify/6]). description() -> "Mobile Push Notifications Module. Wrapper for IOS and Android". -compile(export_all). +-include("roster.hrl"). -fcm_notify(MessageTitle, MessageBody, DeviceId) -> +start() -> + {ok, IOS13} = ios13:start(), + {ok, #{ ios13 => IOS13 + , android => [] + , ios => [] }}. + +fcm_notify(MessageTitle, MessageBody, DeviceId, _ConnState) -> android:notify(MessageTitle, MessageBody, DeviceId). -apns_notify(Alert, Custom, Type, DeviceId, SessionSettings) -> - ios:notify(Alert, Custom, Type, DeviceId, SessionSettings). \ No newline at end of file +apns_notify(Alert, Custom, Type, DeviceId, SessionSettings, ConnState) -> + case ios_version(SessionSettings) of + ios -> + ios:notify(Alert, Custom, Type, DeviceId, SessionSettings); + ios13 -> + IOS13St = maps:get(ios13, ConnState), + ios13:notify(Alert, Custom, Type, DeviceId, SessionSettings, IOS13St) + end. + +ios_version(Settings) -> + case [X || #'Feature'{key = <<"OS">>, value = <<"iOS 13", _/binary>>} = X + <- Settings] of + [_|_] -> + ios13; + [] -> + ios + end. diff --git a/apps/roster/src/protocol/roster_push.erl b/apps/roster/src/protocol/roster_push.erl index b6e67162c..2e91db72b 100644 --- a/apps/roster/src/protocol/roster_push.erl +++ b/apps/roster/src/protocol/roster_push.erl @@ -5,32 +5,37 @@ -include_lib("kvs/include/kvs.hrl"). -compile(export_all). -start() -> n2o_async:start(#handler{module = ?MODULE, class = system, group = roster, name = ?MODULE, state = []}). +start() -> + {ok, ConnState} = push_api:start(), + n2o_async:start(#handler{module = ?MODULE, class = system, group = roster, name = ?MODULE, state = #{conn_state => ConnState}}). proc(init, #handler{name = ?MODULE} = Async) -> ?LOG_INFO("ASYNC", []), {ok, Async}; -proc({async_push, Session, Payload, PushAlert, PushType}, #handler{} = H) -> - send_push_notification(Session, Payload, PushAlert, PushType), +proc({async_push, Session, Payload, PushAlert, PushType}, #handler{state = HS} = H) -> + send_push_notification(Session, Payload, PushAlert, PushType, HS), {reply, [], H}. %% TODO prettify variables naming -send_push_notification(#'Auth'{os = OS, push = PushToken, user_id = PhoneId, settings = AuthSettings}, Payload, PushAlert, PushType) -> +send_push_notification(#'Auth'{ os = OS + , push = PushToken + , user_id = PhoneId + , settings = AuthSettings}, Payload, PushAlert, PushType, HS) -> case PushToken of [] -> skip; _ -> ?LOG_INFO("~p:~p:~pPushAlert:~p", [PhoneId, OS, binary:part(PushToken, 0, erlang:min(25, size(PushToken))), PushAlert]), - send_push_notification(OS, PushToken, Payload, PushAlert, PushType, AuthSettings) + send_push_notification(OS, PushToken, Payload, PushAlert, PushType, AuthSettings, HS) end. -send_push_notification(ios, Push, Payload, PushAlert, <<"calling">>, AuthSettings) -> - push_api:apns_notify(PushAlert, Payload, <<"calling">>, Push, AuthSettings); -send_push_notification(ios, Push, Payload, PushAlert, PushType, AuthSettings) -> +send_push_notification(ios, Push, Payload, PushAlert, <<"calling">>, AuthSettings, HS) -> + push_api:apns_notify(PushAlert, Payload, <<"calling">>, Push, AuthSettings, HS); +send_push_notification(ios, Push, Payload, PushAlert, PushType, AuthSettings, HS) -> DecodedPayload = base64:encode(term_to_binary(Payload)), - push_api:apns_notify(PushAlert, DecodedPayload, PushType, Push, AuthSettings); -send_push_notification(android, Push, Payload, PushAlert, PushType, _) -> + push_api:apns_notify(PushAlert, DecodedPayload, PushType, Push, AuthSettings, HS); +send_push_notification(android, Push, Payload, PushAlert, PushType, _AuthSettings, HS) -> PushModel = #push{model = Payload, type = PushType, alert = PushAlert, title = PushAlert, badge = 1}, AndroidPush = http_uri:encode(binary_to_list(base64:encode(term_to_binary(PushModel)))), - push_api:fcm_notify(PushAlert, AndroidPush, Push); -send_push_notification(_, _, _, _, _, _) -> skip. \ No newline at end of file + push_api:fcm_notify(PushAlert, AndroidPush, Push, HS); +send_push_notification(_, _, _, _, _, _, _) -> skip. diff --git a/apps/roster/src/roster.app.src b/apps/roster/src/roster.app.src index 05a7bdae9..bf95b6384 100644 --- a/apps/roster/src/roster.app.src +++ b/apps/roster/src/roster.app.src @@ -5,7 +5,7 @@ {applications, [kernel,stdlib, mnesia, crypto, inets, ssl, ibrowse, cowboy, mochiweb, gen_smtp, kvs, nitro, n2o, emqttc, emqttd, bpe, - jose, jsx, uuid, erlydtl, jwt, + jose, jsx, uuid, erlydtl, jwt, apns, mini_s3, qdate, rest, enenra, locus, prometheus, libphonenumber_erlang]}, {mod, {roster, []}}, diff --git a/rebar.config b/rebar.config index 4b3d2a4a6..103a68d11 100644 --- a/rebar.config +++ b/rebar.config @@ -15,6 +15,7 @@ {emqttc, {git, "git://github.com/NYNJA-MC/emqttc", {branch,"master"}}}, {rest, {git, "git://github.com/synrc/rest", {tag,"5.10"}}}, {gen_smtp, {git, "git://github.com/voxoz/gen_smtp", {branch,"master"}}}, + {apns, {git, "git://github.com/inaka/apns4erl", {tag, "2.3.1"}}}, {emq_dashboard, {git, "https://github.com/synrc/emq_dashboard", {branch,"master"}}}, {opencensus, {git, "https://github.com/census-instrumentation/opencensus-erlang", {ref, "7fb276f"}}}, {libphonenumber_erlang, {git, "https://github.com/marinakr/libphonenumber_erlang.git", {branch,"master"}}}, @@ -74,7 +75,7 @@ {relx, [{release, {server, {cmd, "git log --pretty=format:'1.1-%h' -n 1"}}, %% Copied from .applist in older version. Should be cleaned up. - [kernel, stdlib, sasl, crypto, inets, os_mon, + [kernel, stdlib, sasl, crypto, inets, os_mon, runtime_tools, fs, gproc, gen_logger, compiler, mnesia, kvs, esockd, @@ -83,7 +84,7 @@ certifi,ibrowse,asn1,xmerl,counters,ctx, wts,syntax_tools,qdate_localtime, libphonenumber_erlang,syn,cowlib,jiffy,idna,parse_trans, - goldrush, public_key,bpe,{lager,load},ssl,ranch, + goldrush, public_key,bpe,{lager,load},ssl,ranch,gun,apns, ssl_verify_fun,locus,emqttd,hackney,roster,service,active, cowboy,emq_dashboard,emqttc,enenra,envy,uuid,erlydtl,forms, gen_smtp, jwt, mini_s3, nitro, opencensus, diff --git a/rebar.lock b/rebar.lock index dae57e48f..2666fc6da 100644 --- a/rebar.lock +++ b/rebar.lock @@ -3,6 +3,11 @@ {git,"git://github.com/synrc/active", {ref,"cdd8f2b0f62b9785673bdbea7be90e1ae1ca1c02"}}, 0}, + {<<"apns">>, + {git,"git://github.com/inaka/apns4erl", + {ref,"c7ee524c349ddc2fd97a4a3dbdb4b3c2c5aaf089"}}, + 0}, + {<<"apns4erl">>,{pkg,<<"apns4erl">>,<<"2.3.1">>},0}, {<<"base64url">>, {git,"https://github.com/dvv/base64url.git", {ref,"f2c64ed8b9bebc536fad37ad97243452b674b837"}}, @@ -86,6 +91,7 @@ {git,"https://github.com/uwiger/gproc", {ref,"1d16f5e6d7cf616eec4395f2385e3a680a4ffc9f"}}, 0}, + {<<"gun">>,{pkg,<<"gun">>,<<"1.3.0">>},1}, {<<"hackney">>, {git,"https://github.com/benoitc/hackney", {ref,"3c32f04ff0783479992a5d11ec0f4a2d09ba922a"}}, @@ -200,9 +206,11 @@ 0}]}. [ {pkg_hash,[ + {<<"apns4erl">>, <<"C7242DC64DD035BA1BBA2BB46895CCCD204853AF0FC232C4200BA1FE457E2ED7">>}, {<<"certifi">>, <<"75424FF0F3BAACCFD34B1214184B6EF616D89E420B258BB0A5EA7D7BC628F7F0">>}, {<<"cf">>, <<"5CB902239476E141EA70A740340233782D363A31EEA8AD37049561542E6CD641">>}, {<<"erlware_commons">>, <<"0CE192AD69BC6FD0880246D852D0ECE17631E234878011D1586E053641ED4C04">>}, + {<<"gun">>, <<"18E5D269649C987AF95AEC309F68A27FFC3930531DD227A6EAA0884D6684286E">>}, {<<"idna">>, <<"689C46CBCDF3524C44D5F3DDE8001F364CD7608A99556D8FBD8239A5798D4C10">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>}, diff --git a/sys.config b/sys.config index c319338ae..ca62fb38d 100644 --- a/sys.config +++ b/sys.config @@ -95,6 +95,7 @@ {app_credentials, "etc/certs/transcribe-dacb4306ab76.json"} ]}, {push_api,[ + {context, dev}, {fcm_server_key,<<"AAAAAzb6_Zg:APA91bGN0jYv_4iqyk8IC4xUdPYXh0yPsTF9YYj_gd9oebRr_ZEoLuC5hCD9RfdqA3Y3AF_P_WbelqvzvgR3RsX_mHBLynV14Q6HakXAtrY_eWLK2xqamF2OC9uBXfKgxTFFqmyr1Kbw">>}, {apns_cert_dir,<<"apns_certificates">>}, {apns_port,2195}]}, -- GitLab From 8c902d6fb85e332b87ccddac16abed1347987945 Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Wed, 6 May 2020 08:44:52 +0200 Subject: [PATCH 2/6] fix paths to pem files --- apps/roster/src/api/push/ios13.erl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/roster/src/api/push/ios13.erl b/apps/roster/src/api/push/ios13.erl index 1a2a927ec..5a0beeda1 100644 --- a/apps/roster/src/api/push/ios13.erl +++ b/apps/roster/src/api/push/ios13.erl @@ -8,9 +8,7 @@ description() -> "iOS 13.x Push Notifications Module". --define(APNS_CERT_DIR, proplists:get_value(apns_cert_dir, - push_api_opts(), - default_cert_dir())). +-define(APNS_CERT_DIR, apns_cert_dir()). -define(APNS_PORT, proplists:get_value(apns_port, push_api_opts(), 443)). @@ -79,6 +77,21 @@ keyfile(Context) -> end, filename:join(?APNS_CERT_DIR, Base). +apns_cert_dir() -> + D = proplists:get_value(apns_cert_dir, push_api_opts(), + default_cert_dir()), + Priv = code:priv_dir(roster), + case D of + "apps/roster/" ++ _ -> + filename:join(Priv, filename:basename(D)); + "priv/" ++ Rest -> + filename:join(Priv, Rest); + "/" ++ _ -> + D; + Rel -> + filename:join(Priv, Rel) + end. + default_cert_dir() -> filename:join(code:priv_dir(roster), "apns_certificates"). -- GitLab From bbe5abb2bd2bd07f82fbaa444c35049b81a3c91d Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Wed, 6 May 2020 10:44:59 +0200 Subject: [PATCH 3/6] fix cert_dir and port defaults --- apps/roster/src/api/push/ios13.erl | 38 ++++++++++++------------------ sys.config | 3 +-- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/apps/roster/src/api/push/ios13.erl b/apps/roster/src/api/push/ios13.erl index 5a0beeda1..80892fed4 100644 --- a/apps/roster/src/api/push/ios13.erl +++ b/apps/roster/src/api/push/ios13.erl @@ -23,19 +23,7 @@ description() -> "iOS 13.x Push Notifications Module". ]). start() -> - dbg:tracer(), - dbg:tpl(?MODULE, x), - dbg:tp(apns, x), - dbg:tp(gun, x), - dbg:tp(gen_tcp,connect,x), - dbg:p(all,[c]), - try start(detect_context()) - after - timer:sleep(1000), - dbg:ctpl('_'), - dbg:ctp('_'), - dbg:stop() - end. + start(detect_context()). start(Context) -> Conn = #{ name => ios13 @@ -81,20 +69,24 @@ apns_cert_dir() -> D = proplists:get_value(apns_cert_dir, push_api_opts(), default_cert_dir()), Priv = code:priv_dir(roster), - case D of - "apps/roster/" ++ _ -> - filename:join(Priv, filename:basename(D)); - "priv/" ++ Rest -> - filename:join(Priv, Rest); - "/" ++ _ -> - D; - Rel -> - filename:join(Priv, Rel) - end. + Res = case D of + "apps/roster/" ++ _ -> + filename:join(Priv, filename:basename(D)); + "priv/" ++ Rest -> + filename:join(Priv, Rest); + "/" ++ _ -> + D; + Rel -> + filename:join(Priv, Rel) + end, + string(Res). default_cert_dir() -> filename:join(code:priv_dir(roster), "apns_certificates"). +string(S) -> + binary_to_list(iolist_to_binary(S)). + %% ------------------------------------------------------------------ %% Ios Push Notifications %% ------------------------------------------------------------------ diff --git a/sys.config b/sys.config index ca62fb38d..6e0bad93a 100644 --- a/sys.config +++ b/sys.config @@ -97,8 +97,7 @@ {push_api,[ {context, dev}, {fcm_server_key,<<"AAAAAzb6_Zg:APA91bGN0jYv_4iqyk8IC4xUdPYXh0yPsTF9YYj_gd9oebRr_ZEoLuC5hCD9RfdqA3Y3AF_P_WbelqvzvgR3RsX_mHBLynV14Q6HakXAtrY_eWLK2xqamF2OC9uBXfKgxTFFqmyr1Kbw">>}, - {apns_cert_dir,<<"apns_certificates">>}, - {apns_port,2195}]}, + {apns_cert_dir,<<"apns_certificates">>}]}, {job_delay, 60}, %% 1 mins {auth_ttl, 900}, %% 15 mins {auth_check_ip, false}, -- GitLab From d617303c2d2ec7e766668c4fdd634191a5f81b79 Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Wed, 6 May 2020 10:55:10 +0200 Subject: [PATCH 4/6] remove runtime_tools again --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 103a68d11..e92c45651 100644 --- a/rebar.config +++ b/rebar.config @@ -75,7 +75,7 @@ {relx, [{release, {server, {cmd, "git log --pretty=format:'1.1-%h' -n 1"}}, %% Copied from .applist in older version. Should be cleaned up. - [kernel, stdlib, sasl, crypto, inets, os_mon, runtime_tools, + [kernel, stdlib, sasl, crypto, inets, os_mon, fs, gproc, gen_logger, compiler, mnesia, kvs, esockd, -- GitLab From c7c17bdc853ff351721c1e11d3ca5e7c2690fe9a Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Thu, 7 May 2020 16:49:53 +0200 Subject: [PATCH 5/6] Address review comments --- apps/roster/src/api/push/ios13.erl | 15 +-------------- sys.config | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/apps/roster/src/api/push/ios13.erl b/apps/roster/src/api/push/ios13.erl index 80892fed4..56a7b8748 100644 --- a/apps/roster/src/api/push/ios13.erl +++ b/apps/roster/src/api/push/ios13.erl @@ -69,24 +69,11 @@ apns_cert_dir() -> D = proplists:get_value(apns_cert_dir, push_api_opts(), default_cert_dir()), Priv = code:priv_dir(roster), - Res = case D of - "apps/roster/" ++ _ -> - filename:join(Priv, filename:basename(D)); - "priv/" ++ Rest -> - filename:join(Priv, Rest); - "/" ++ _ -> - D; - Rel -> - filename:join(Priv, Rel) - end, - string(Res). + filename:join(Priv, D). default_cert_dir() -> filename:join(code:priv_dir(roster), "apns_certificates"). -string(S) -> - binary_to_list(iolist_to_binary(S)). - %% ------------------------------------------------------------------ %% Ios Push Notifications %% ------------------------------------------------------------------ diff --git a/sys.config b/sys.config index 6e0bad93a..83e75cc9c 100644 --- a/sys.config +++ b/sys.config @@ -97,7 +97,7 @@ {push_api,[ {context, dev}, {fcm_server_key,<<"AAAAAzb6_Zg:APA91bGN0jYv_4iqyk8IC4xUdPYXh0yPsTF9YYj_gd9oebRr_ZEoLuC5hCD9RfdqA3Y3AF_P_WbelqvzvgR3RsX_mHBLynV14Q6HakXAtrY_eWLK2xqamF2OC9uBXfKgxTFFqmyr1Kbw">>}, - {apns_cert_dir,<<"apns_certificates">>}]}, + {apns_cert_dir, "apns_certificates"}]}, {job_delay, 60}, %% 1 mins {auth_ttl, 900}, %% 15 mins {auth_check_ip, false}, -- GitLab From 5aa5051f92d051e0766311e3ca822877425de6e5 Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Mon, 11 May 2020 14:11:32 +0200 Subject: [PATCH 6/6] Use own apns4erl fork; add status debug function --- apps/roster/src/api/push/ios13.erl | 57 +++++++++++++++++++++++++++++- rebar.config | 2 +- rebar.lock | 4 +-- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/apps/roster/src/api/push/ios13.erl b/apps/roster/src/api/push/ios13.erl index 56a7b8748..a071847c3 100644 --- a/apps/roster/src/api/push/ios13.erl +++ b/apps/roster/src/api/push/ios13.erl @@ -6,6 +6,8 @@ -export([start/0]). -export([description/0, notify/6, test_push_notification/0]). +-export([status/0]). + description() -> "iOS 13.x Push Notifications Module". -define(APNS_CERT_DIR, apns_cert_dir()). @@ -31,9 +33,19 @@ start(Context) -> , apple_port => ?APNS_PORT , certfile => certfile(Context) , keyfile => keyfile(Context) - , type => cert }, + , type => cert + , gun => #{ transport => tls + , http2_opts => #{ keepalive => 30000 } + } + }, apns:connect(Conn). +%% For debugging purposes. Should be replaced by a more +%% structured solution. +status() -> + Ch = supervisor:which_children(apns_sup), + [ch_status(Pid) || {_, Pid, worker, [apns_connection]} <- Ch]. + detect_context() -> proplists:get_value(context, push_api_opts(), dev). @@ -129,6 +141,49 @@ get_data_from_feature(SessionSettings, Key) -> %% end %% end. +ch_status(Pid) -> + case sys:get_status(Pid) of + {status, _, {module, gen_statem}, + [_, running, _, _, + [ {header, _} + , {data, _} + , {data, [{"State", {Status, St}}]} + ]]} -> + ch_status(Pid, Status, St); + _Other -> + {Pid, undefined} + end. + +ch_status(Pid, connected, St) -> + GunPid = maps:get(gun_pid, St), + {Pid, #{ status => connected + , state => St + , gun => gun_status(GunPid) }}; +ch_status(Pid, Other, St) -> + {Pid, Other, St}. + +gun_status(Pid) -> + case sys:get_status(Pid) of + {status, _, {module, _}, + [ _, running, _, _ + , {loop, State}] + } -> + case State of + _ when element(1, State) == state -> + case [M || M <- tuple_to_list(State), + is_map(M)] of + [GunOpts] -> + GunOpts; + _ -> + undefined + end; + _ -> + undefined + end; + _Other -> + undefined + end. + %% ------------------------------------------------------------------ %% Tests %% ------------------------------------------------------------------ diff --git a/rebar.config b/rebar.config index e92c45651..5ce1cd820 100644 --- a/rebar.config +++ b/rebar.config @@ -15,7 +15,7 @@ {emqttc, {git, "git://github.com/NYNJA-MC/emqttc", {branch,"master"}}}, {rest, {git, "git://github.com/synrc/rest", {tag,"5.10"}}}, {gen_smtp, {git, "git://github.com/voxoz/gen_smtp", {branch,"master"}}}, - {apns, {git, "git://github.com/inaka/apns4erl", {tag, "2.3.1"}}}, + {apns, {git, "git://github.com/NYNJA-MC/apns4erl", {ref, "6724edcf073f512a01a0b7652223d173db2f2fe0"}}}, {emq_dashboard, {git, "https://github.com/synrc/emq_dashboard", {branch,"master"}}}, {opencensus, {git, "https://github.com/census-instrumentation/opencensus-erlang", {ref, "7fb276f"}}}, {libphonenumber_erlang, {git, "https://github.com/marinakr/libphonenumber_erlang.git", {branch,"master"}}}, diff --git a/rebar.lock b/rebar.lock index 2666fc6da..11bbab7a5 100644 --- a/rebar.lock +++ b/rebar.lock @@ -4,8 +4,8 @@ {ref,"cdd8f2b0f62b9785673bdbea7be90e1ae1ca1c02"}}, 0}, {<<"apns">>, - {git,"git://github.com/inaka/apns4erl", - {ref,"c7ee524c349ddc2fd97a4a3dbdb4b3c2c5aaf089"}}, + {git,"git://github.com/NYNJA-MC/apns4erl", + {ref,"6724edcf073f512a01a0b7652223d173db2f2fe0"}}, 0}, {<<"apns4erl">>,{pkg,<<"apns4erl">>,<<"2.3.1">>},0}, {<<"base64url">>, -- GitLab