• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

processone / ejabberd / 1212

18 Nov 2025 12:37PM UTC coverage: 33.784% (+0.003%) from 33.781%
1212

push

github

badlop
mod_conversejs: Improve link to conversejs in WebAdmin (#4495)

Until now, the WebAdmin menu included a link to the first request handler
with mod_conversejs that the admin configured in ejabberd.yml
That link included the authentication credentials hashed as URI arguments
if using HTTPS. Then process/2 extracted those arguments and passed them
as autologin options to Converse.

From now, mod_conversejs automatically adds a request_handler nested in
webadmin subpath. The webadmin menu links to that converse URI; this allows
to access the HTTP auth credentials, no need to explicitly pass them.
process/2 extracts this HTTP auth and passes autologin options to Converse.
Now scram password storage is supported too.

This minimum configuration allows WebAdmin to access Converse:

listen:
  -
    port: 5443
    module: ejabberd_http
    tls: true
    request_handlers:
      /admin: ejabberd_web_admin
      /ws: ejabberd_http_ws
modules:
  mod_conversejs:
    conversejs_resources: "/home/conversejs/12.0.0/dist"

0 of 12 new or added lines in 1 file covered. (0.0%)

11290 existing lines in 174 files now uncovered.

15515 of 45924 relevant lines covered (33.78%)

1277.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.78
/src/mod_proxy65_mnesia.erl
1
%%%-------------------------------------------------------------------
2
%%% Created : 16 Jan 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
3
%%%
4
%%%
5
%%% ejabberd, Copyright (C) 2002-2025   ProcessOne
6
%%%
7
%%% This program is free software; you can redistribute it and/or
8
%%% modify it under the terms of the GNU General Public License as
9
%%% published by the Free Software Foundation; either version 2 of the
10
%%% License, or (at your option) any later version.
11
%%%
12
%%% This program is distributed in the hope that it will be useful,
13
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
14
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
%%% General Public License for more details.
16
%%%
17
%%% You should have received a copy of the GNU General Public License along
18
%%% with this program; if not, write to the Free Software Foundation, Inc.,
19
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
%%%
21
%%%-------------------------------------------------------------------
22
-module(mod_proxy65_mnesia).
23
-behaviour(gen_server).
24
-behaviour(mod_proxy65).
25

26
%% API
27
-export([init/0, register_stream/2, unregister_stream/1, activate_stream/4]).
28
-export([start_link/0]).
29
%% gen_server callbacks
30
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
31
         terminate/2, code_change/3]).
32

33
-include("logger.hrl").
34

35
-record(bytestream,
36
        {sha1 = <<"">> :: binary() | '$1',
37
         target :: pid() | '_',
38
         initiator :: pid() | '_' | undefined,
39
         active = false :: boolean() | '_',
40
         jid_i :: undefined | binary() | '_'}).
41

42
-record(state, {}).
43

44
%%%===================================================================
45
%%% API
46
%%%===================================================================
47
start_link() ->
48
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
16✔
49

50
init() ->
51
    Spec = {?MODULE, {?MODULE, start_link, []}, transient,
144✔
52
            5000, worker, [?MODULE]},
53
    supervisor:start_child(ejabberd_backend_sup, Spec).
144✔
54

55
register_stream(SHA1, StreamPid) ->
UNCOV
56
    F = fun () ->
4✔
UNCOV
57
                case mnesia:read(bytestream, SHA1, write) of
4✔
58
                    [] ->
UNCOV
59
                        mnesia:write(#bytestream{sha1 = SHA1,
2✔
60
                                                 target = StreamPid});
61
                    [#bytestream{target = Pid, initiator = undefined} =
62
                         ByteStream] when is_pid(Pid), Pid /= StreamPid ->
UNCOV
63
                        mnesia:write(ByteStream#bytestream{
2✔
64
                                       initiator = StreamPid})
65
                end
66
        end,
UNCOV
67
    case mnesia:transaction(F) of
4✔
68
        {atomic, ok} ->
UNCOV
69
            ok;
4✔
70
        {aborted, Reason} ->
71
            ?ERROR_MSG("Mnesia transaction failed: ~p", [Reason]),
×
72
            {error, Reason}
×
73
    end.
74

75
unregister_stream(SHA1) ->
UNCOV
76
    F = fun () -> mnesia:delete({bytestream, SHA1}) end,
4✔
UNCOV
77
    case mnesia:transaction(F) of
4✔
78
        {atomic, ok} ->
UNCOV
79
            ok;
4✔
80
        {aborted, Reason} ->
81
            ?ERROR_MSG("Mnesia transaction failed: ~p", [Reason]),
×
82
            {error, Reason}
×
83
    end.
84

85
activate_stream(SHA1, Initiator, MaxConnections, _Node) ->
UNCOV
86
    case gen_server:call(?MODULE,
2✔
87
                         {activate_stream, SHA1, Initiator, MaxConnections}) of
88
        {atomic, {ok, IPid, TPid}} ->
UNCOV
89
            {ok, IPid, TPid};
2✔
90
        {atomic, {limit, IPid, TPid}} ->
91
            {error, {limit, IPid, TPid}};
×
92
        {atomic, conflict} ->
93
            {error, conflict};
×
94
        {atomic, notfound} ->
95
            {error, notfound};
×
96
        Err ->
97
            {error, Err}
×
98
    end.
99

100
%%%===================================================================
101
%%% gen_server callbacks
102
%%%===================================================================
103
init([]) ->
104
    ejabberd_mnesia:create(?MODULE, bytestream,
16✔
105
                           [{ram_copies, [node()]},
106
                            {attributes, record_info(fields, bytestream)}]),
107
    {ok, #state{}}.
16✔
108

109
handle_call({activate_stream, SHA1, Initiator, MaxConnections}, _From, State) ->
UNCOV
110
    F = fun () ->
2✔
UNCOV
111
                case mnesia:read(bytestream, SHA1, write) of
2✔
112
                    [#bytestream{target = TPid, initiator = IPid} =
113
                         ByteStream] when is_pid(TPid), is_pid(IPid) ->
UNCOV
114
                        ActiveFlag = ByteStream#bytestream.active,
2✔
UNCOV
115
                        if ActiveFlag == false ->
2✔
UNCOV
116
                                ConnsPerJID = mnesia:select(
2✔
117
                                                bytestream,
118
                                                [{#bytestream{sha1 = '$1',
119
                                                              jid_i = Initiator,
120
                                                              _ = '_'},
121
                                                  [], ['$1']}]),
UNCOV
122
                                if length(ConnsPerJID) < MaxConnections ->
2✔
UNCOV
123
                                        mnesia:write(
2✔
124
                                          ByteStream#bytestream{active = true,
125
                                                                jid_i = Initiator}),
UNCOV
126
                                        {ok, IPid, TPid};
2✔
127
                                   true ->
128
                                        {limit, IPid, TPid}
×
129
                                end;
130
                           true ->
131
                                conflict
×
132
                        end;
133
                    _ ->
134
                        notfound
×
135
                end
136
        end,
UNCOV
137
    Reply = mnesia:transaction(F),
2✔
UNCOV
138
    {reply, Reply, State};
2✔
139
handle_call(Request, From, State) ->
140
    ?WARNING_MSG("Unexpected call from ~p: ~p", [From, Request]),
×
141
    {noreply, State}.
×
142

143
handle_cast(Msg, State) ->
144
    ?WARNING_MSG("Unexpected cast: ~p", [Msg]),
×
145
    {noreply, State}.
×
146

147
handle_info(Info, State) ->
148
    ?WARNING_MSG("Unexpected info: ~p", [Info]),
×
149
    {noreply, State}.
×
150

151
terminate(_Reason, _State) ->
152
    ok.
×
153

154
code_change(_OldVsn, State, _Extra) ->
155
    {ok, State}.
×
156

157
%%%===================================================================
158
%%% Internal functions
159
%%%===================================================================
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc