Add option to auto-register your nickname to a room
See https://xmpp.org/extensions/xep-0045.html#register
This commit is contained in:
parent
764686dd19
commit
2df9b24211
@ -111,7 +111,7 @@
|
||||
"no-bitwise": "off",
|
||||
"no-caller": "error",
|
||||
"no-console": "off",
|
||||
"no-catch-shadow": "error",
|
||||
"no-catch-shadow": "off",
|
||||
"no-cond-assign": [
|
||||
"error",
|
||||
"except-parens"
|
||||
|
35
CHANGES.md
35
CHANGES.md
@ -2,6 +2,7 @@
|
||||
|
||||
## 4.0.1 (Unreleased)
|
||||
|
||||
- New configuration setting [auto_register_muc_nickname](https://conversejs.org/docs/html/configuration.html#auto-register-muc-nickname)
|
||||
- #1182 MUC occupants without nick or JID created
|
||||
- #1184 Notification error when message has no body
|
||||
|
||||
@ -30,7 +31,7 @@
|
||||
If the device is not trusted, sessionStorage is used and all user data is deleted from the browser cache upon logout.
|
||||
If the device is trusted, localStorage is used and user data is cached indefinitely.
|
||||
- Initial support for [XEP-0357 Push Notifications](https://xmpp.org/extensions/xep-0357.html), specifically registering an "App Server".
|
||||
- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configurations.html#oauth-providers) setting)
|
||||
- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configuration.html#oauth-providers) setting)
|
||||
|
||||
### Bugfixes
|
||||
|
||||
@ -61,7 +62,7 @@
|
||||
|
||||
## Configuration changes
|
||||
|
||||
- Removed the `storage` configuration setting, use [trusted](https://conversejs.org/docs/html/configurations.html#trusted) instead.
|
||||
- Removed the `storage` configuration setting, use [trusted](https://conversejs.org/docs/html/configuration.html#trusted) instead.
|
||||
- Removed the `use_vcards` configuration setting, instead VCards are always used.
|
||||
- Removed the `xhr_custom_status` and `xhr_custom_status_url` configuration
|
||||
settings. If you relied on these settings, you can instead listen for the
|
||||
@ -71,8 +72,8 @@
|
||||
- `xhr_user_search_url` has to include the `?` character now in favor of more flexibility. See example in the documentation.
|
||||
- The data returned from the `xhr_user_search_url` must now include the user's
|
||||
`jid` instead of just an `id`.
|
||||
- New configuration settings [nickname](https://conversejs.org/docs/html/configurations.html#nickname)
|
||||
and [auto_join_private_chats](https://conversejs.org/docs/html/configurations.html#auto-join-private-chats).
|
||||
- New configuration settings [nickname](https://conversejs.org/docs/html/configuration.html#nickname)
|
||||
and [auto_join_private_chats](https://conversejs.org/docs/html/configuration.html#auto-join-private-chats).
|
||||
|
||||
## Architectural changes
|
||||
|
||||
@ -133,7 +134,7 @@
|
||||
- Listen for new room bookmarks pushed from the user's PEP service.
|
||||
- Simplified the [embedded](https://conversejs.org/demo/embedded.html) usecase.
|
||||
- No need to manually blacklist or whitelist any plugins.
|
||||
- Relies on the [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode) being set to `'embedded'`.
|
||||
- Relies on the [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) being set to `'embedded'`.
|
||||
- The main `converse.js` build can be used for the embedded usecase.
|
||||
- Maintain MUC session upon page reload
|
||||
|
||||
@ -142,9 +143,9 @@
|
||||
|
||||
### Configuration settings
|
||||
- `auto_reconnect` is now set to `true` by default.
|
||||
- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configurations.html#allow-public-bookmarks)
|
||||
- New configuration setting [root](https://conversejs.org/docs/html/configurations.html#root)
|
||||
- The [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode) setting now has a new possible value: `embedded`
|
||||
- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configuration.html#allow-public-bookmarks)
|
||||
- New configuration setting [root](https://conversejs.org/docs/html/configuration.html#root)
|
||||
- The [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode) setting now has a new possible value: `embedded`
|
||||
|
||||
### Translation updates
|
||||
- Chinese (Traditional), French, German, Portuguese (Brazil), Russian, Ukrainian
|
||||
@ -173,7 +174,7 @@
|
||||
|
||||
### UI/UX changes
|
||||
- Add new configuration option
|
||||
[show_message_load_animation](https://conversejs.org/docs/html/configurations.html#show-message-load-animation)
|
||||
[show_message_load_animation](https://conversejs.org/docs/html/configuration.html#show-message-load-animation)
|
||||
with a default value of `false`. The message load animations (added in 3.3.0)
|
||||
cause slowness and performance issues in Firefox, so they're now disabled by default.
|
||||
|
||||
@ -210,7 +211,7 @@
|
||||
and private chats with a URL fragment such as `#converse/chat?jid=user@domain`
|
||||
- #828 Add routing for the `#converse/login` and `#converse/register` URL
|
||||
fragments, which will render the registration and login forms respectively.
|
||||
- New configuration setting [view_mode](https://conversejs.org/docs/html/configurations.html#view-mode)
|
||||
- New configuration setting [view_mode](https://conversejs.org/docs/html/configuration.html#view-mode)
|
||||
This removes the need for separate `inverse.js` and `converse-mobile.js`
|
||||
builds. Instead the `converse.js` build is now used with `view_mode` set to
|
||||
`fullscreen` and `mobile` respectively.
|
||||
@ -248,7 +249,7 @@
|
||||
- Converse.js no longer includes all the translations in its build. Instead,
|
||||
only the currently relevant translation is requested. This results in a much
|
||||
smaller filesize but means that the translations you want to provide need to
|
||||
be available. See the [locales_url](https://conversejs.org/docs/html/configurations.html#locales-url)
|
||||
be available. See the [locales_url](https://conversejs.org/docs/html/configuration.html#locales-url)
|
||||
configuration setting for more info.
|
||||
- The translation machinery has now been moved to a separate module in `src/i18n.js`.
|
||||
- jQuery has been completely removed as a dependency (still used in tests though).
|
||||
@ -277,10 +278,10 @@
|
||||
|
||||
### New configuration settings
|
||||
* The `visible_toolbar_buttons.emoticons` configuration option is now changed to `visible_toolbar_buttons.emoji`.
|
||||
* [use_emojione](https://conversejs.org/docs/html/configurations.html#use-emojione)
|
||||
* [use_emojione](https://conversejs.org/docs/html/configuration.html#use-emojione)
|
||||
is used to determine whether Emojione should be used to render emojis,
|
||||
otherwise rendering falls back to native browser or OS support.
|
||||
* [emojione_image_path](https://conversejs.org/docs/html/configurations.html#emojione-image-path)
|
||||
* [emojione_image_path](https://conversejs.org/docs/html/configuration.html#emojione-image-path)
|
||||
is used to specify from where Emojione will load images for rendering emojis.
|
||||
|
||||
### New events
|
||||
@ -334,7 +335,7 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
|
||||
|
||||
### New configuration settings
|
||||
- New setting for `converse-bookmarks`:
|
||||
[hide_open_bookmarks](https://conversejs.org/docs/html/configurations.html#hide-open-bookmarks)
|
||||
[hide_open_bookmarks](https://conversejs.org/docs/html/configuration.html#hide-open-bookmarks)
|
||||
It is meant to be set to `true` when using `converse-roomslist` so that open
|
||||
rooms aren't listed twice (in the rooms list and the bookmarks list).
|
||||
[jcbrand]
|
||||
@ -388,13 +389,13 @@ More info here: https://github.com/LeaVerou/awesomplete/pull/17082
|
||||
- #628 Fixes the bug in displaying chat status during private chat. [saganshul]
|
||||
- #628 Changes the message displayed while typing from a different resource of the same user. [smitbose]
|
||||
- #675 Time format made configurable.
|
||||
See [time_format](https://conversejs.org/docs/html/configurations.html#time-format)
|
||||
See [time_format](https://conversejs.org/docs/html/configuration.html#time-format)
|
||||
[smitbose]
|
||||
- #682 Add "Send" button to input box in chat dialog window.
|
||||
See [show_send_button](https://conversejs.org/docs/html/configurations.html#show-send-button)
|
||||
See [show_send_button](https://conversejs.org/docs/html/configuration.html#show-send-button)
|
||||
[saganshul]
|
||||
- #704 Automatic fetching of registration form when
|
||||
[registration_domain](https://conversejs.org/docs/html/configurations.html#registration-domain)
|
||||
[registration_domain](https://conversejs.org/docs/html/configuration.html#registration-domain)
|
||||
is set. [smitbose]
|
||||
- #806 The `_converse.listen` API event listeners aren't triggered. [jcbrand]
|
||||
- #807 Error: Plugin "converse-dragresize" tried to override HeadlinesBoxView but it's not found. [jcbrand]
|
||||
|
85
dist/converse.js
vendored
85
dist/converse.js
vendored
@ -62864,6 +62864,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
||||
Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
|
||||
Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob');
|
||||
Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
|
||||
Strophe.addNamespace('REGISTER', 'jabber:iq:register');
|
||||
Strophe.addNamespace('ROSTERX', 'http://jabber.org/protocol/rosterx');
|
||||
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
||||
Strophe.addNamespace('SID', 'urn:xmpp:sid:0');
|
||||
@ -68982,10 +68983,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
||||
* If so, we'll use that, otherwise we render the nickname form.
|
||||
*/
|
||||
this.showSpinner();
|
||||
this.model.checkForReservedNick(this.onNickNameFound.bind(this), this.onNickNameNotFound.bind(this));
|
||||
this.model.checkForReservedNick(this.onReservedNicknameFound.bind(this), this.onReservedNicknameNotFound.bind(this));
|
||||
},
|
||||
|
||||
onNickNameFound(iq) {
|
||||
onReservedNicknameFound(iq) {
|
||||
/* We've received an IQ response from the server which
|
||||
* might contain the user's reserved nickname.
|
||||
* If no nickname is found we either render a form for
|
||||
@ -69005,7 +69006,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
||||
}
|
||||
},
|
||||
|
||||
onNickNameNotFound(message) {
|
||||
onReservedNicknameNotFound(message) {
|
||||
const nick = this.getDefaultNickName();
|
||||
|
||||
if (nick) {
|
||||
@ -70032,6 +70033,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
||||
allow_muc_invitations: true,
|
||||
auto_join_on_invite: false,
|
||||
auto_join_rooms: [],
|
||||
auto_register_muc_nickname: false,
|
||||
muc_domain: undefined,
|
||||
muc_history_max_stanzas: undefined,
|
||||
muc_instant_rooms: true,
|
||||
@ -70100,12 +70102,24 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
||||
initialize() {
|
||||
this.constructor.__super__.initialize.apply(this, arguments);
|
||||
|
||||
this.on('change:connection_status', this.onConnectionStatusChanged, this);
|
||||
this.occupants = new _converse.ChatRoomOccupants();
|
||||
this.occupants.browserStorage = new Backbone.BrowserStorage.session(b64_sha1(`converse.occupants-${_converse.bare_jid}${this.get('jid')}`));
|
||||
this.occupants.chatroom = this;
|
||||
this.registerHandlers();
|
||||
},
|
||||
|
||||
async onConnectionStatusChanged() {
|
||||
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED && _converse.auto_register_muc_nickname) {
|
||||
debugger;
|
||||
const result = await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'));
|
||||
|
||||
if (result.length) {
|
||||
this.registerNickname();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
registerHandlers() {
|
||||
/* Register presence and message handlers for this chat
|
||||
* groupchat
|
||||
@ -70808,6 +70822,53 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
||||
return this;
|
||||
},
|
||||
|
||||
async registerNickname() {
|
||||
try {
|
||||
await _converse.api.sendIQ($iq({
|
||||
'from': _converse.bare_jid,
|
||||
'to': this.get('jid'),
|
||||
'type': 'get'
|
||||
}).c('query', {
|
||||
'xmlns': Strophe.NS.MUC_REGISTER
|
||||
}));
|
||||
} catch (e) {
|
||||
if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')} which does not exist.`);
|
||||
} else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`You're not allowed to register in the groupchat ${this.get('jid')}`);
|
||||
}
|
||||
|
||||
return _converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
|
||||
try {
|
||||
await _converse.api.sendIQ($iq({
|
||||
'from': _converse.bare_jid,
|
||||
'to': this.get('jid'),
|
||||
'type': 'set'
|
||||
}).c('query', {
|
||||
'xmlns': Strophe.NS.MUC_REGISTER
|
||||
}).c('x', {
|
||||
'xmlns': Strophe.NS.XFORM,
|
||||
'type': 'submit'
|
||||
}).c('field', {
|
||||
'var': 'FORM_TYPE'
|
||||
}).c('value').t('http://jabber.org/protocol/muc#register').up().up().c('field', {
|
||||
'var': 'muc#register_roomnick'
|
||||
}).c('value').t(this.get('nick')));
|
||||
} catch (e) {
|
||||
if (sizzle('conflict[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it's already taken.`);
|
||||
} else if (sizzle('service-unavailable[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it doesn't support registration.`);
|
||||
} else if (sizzle('bad-request[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, invalid data form supplied.`);
|
||||
}
|
||||
|
||||
return _converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
},
|
||||
|
||||
updateOccupantsOnPresence(pres) {
|
||||
/* Given a presence stanza, update the occupant model
|
||||
* based on its contents.
|
||||
@ -71330,6 +71391,22 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRegistrationForm(room_jid, user_jid) {
|
||||
_converse.api.sendIQ($iq({
|
||||
'from': user_jid,
|
||||
'to': room_jid,
|
||||
'type': 'get'
|
||||
}).c('query', {
|
||||
'xmlns': Strophe.NS.REGISTER
|
||||
})).then(iq => {}).catch(iq => {
|
||||
if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', iq).length) {
|
||||
this.feedback.set('error', __(`Error: the groupchat ${this.model.getDisplayName()} does not exist.`));
|
||||
} else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
||||
this.feedback.set('error', __(`Sorry, you're not allowed to registerd in this groupchat`));
|
||||
}
|
||||
});
|
||||
}
|
||||
/************************ BEGIN Event Handlers ************************/
|
||||
|
||||
|
||||
@ -78494,6 +78571,8 @@ __e(o.info_configure) +
|
||||
} ;
|
||||
__p += '\n <a class="chatbox-btn show-room-details-modal fa fa-info-circle" title="' +
|
||||
__e(o.info_details) +
|
||||
'"></a>\n <a class="chatbox-btn show-room-registration-modal fa fa-file-signature" title="' +
|
||||
__e(o.info_register) +
|
||||
'"></a>\n</div>\n';
|
||||
return __p
|
||||
};
|
||||
|
@ -328,6 +328,16 @@ wiped from memory. This configuration can however still be useful when using
|
||||
Converse in desktop apps, for example those based on `CEF <https://bitbucket.org/chromiumembedded/cef>`_
|
||||
or `electron <http://electron.atom.io/>`_.
|
||||
|
||||
auto_register_muc_nickname
|
||||
--------------------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
Determines whether Converse should automatically register a user's nickname
|
||||
when they enter a groupchat.
|
||||
|
||||
See here fore more details: https://xmpp.org/extensions/xep-0045.html#register
|
||||
|
||||
auto_subscribe
|
||||
--------------
|
||||
|
||||
|
2
sass/font-awesome.scss
vendored
2
sass/font-awesome.scss
vendored
@ -10,7 +10,6 @@
|
||||
url('webfonts/fa-brands-400.svg#fontawesome') format('svg');
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'ConverseFontAwesomeRegular';
|
||||
font-style: normal;
|
||||
@ -46,6 +45,7 @@
|
||||
font-family: 'ConverseFontAwesomeSolid' !important;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.fab {
|
||||
font-family: 'ConverseFontAwesomeBrands';
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
Backbone = converse.env.Backbone,
|
||||
u = converse.env.utils;
|
||||
|
||||
return describe("ChatRooms", function () {
|
||||
return describe("Chatrooms", function () {
|
||||
describe("The \"rooms\" API", function () {
|
||||
|
||||
it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
|
||||
@ -816,9 +816,8 @@
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
var view;
|
||||
var sent_IQ, IQ_id;
|
||||
var sendIQ = _converse.connection.sendIQ;
|
||||
let view, sent_IQ, IQ_id;
|
||||
const sendIQ = _converse.connection.sendIQ;
|
||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||
sent_IQ = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
|
44
spec/room_registration.js
Normal file
44
spec/room_registration.js
Normal file
@ -0,0 +1,44 @@
|
||||
(function (root, factory) {
|
||||
define(["jasmine", "mock", "test-utils" ], factory);
|
||||
} (this, function (jasmine, mock, test_utils) {
|
||||
const _ = converse.env._,
|
||||
$iq = converse.env.$iq,
|
||||
Strophe = converse.env.Strophe,
|
||||
u = converse.env.utils;
|
||||
|
||||
describe("The _converse.api.rooms API", function () {
|
||||
|
||||
it("allows you to register a user with a room",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
let view;
|
||||
const room_jid = 'coven@chat.shakespeare.lit';
|
||||
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo')
|
||||
.then(() => {
|
||||
view = _converse.chatboxviews.get(room_jid);
|
||||
_converse.api.rooms.register(room_jid, _converse.bare_jid, 'romeo');
|
||||
return test_utils.waitUntil(() => _.get(_.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => iq.nodeTree.querySelector(`iq[to="coven@chat.shakespeare.lit"] query[xmlns="jabber:iq:register"]`)
|
||||
).pop(), 'nodeTree'));
|
||||
}).then(stanza => {
|
||||
expect(stanza.outerHTML)
|
||||
.toBe(`<iq from="dummy@localhost" to="coven@chat.shakespeare.lit" `+
|
||||
`type="get" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
|
||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||
// Room does not exist
|
||||
const result = $iq({
|
||||
'from': view.model.get('jid'),
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': _converse.bare_jid,
|
||||
'type': 'error',
|
||||
}).c('error', {'type': "cancel"})
|
||||
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"})
|
||||
_converse.connection._dataRecv(test_utils.createRequest(result));
|
||||
done();
|
||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||
}));
|
||||
});
|
||||
}));
|
@ -39,6 +39,7 @@
|
||||
Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
|
||||
Strophe.addNamespace('OUTOFBAND', 'jabber:x:oob');
|
||||
Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
|
||||
Strophe.addNamespace('REGISTER', 'jabber:iq:register');
|
||||
Strophe.addNamespace('ROSTERX', 'http://jabber.org/protocol/rosterx');
|
||||
Strophe.addNamespace('RSM', 'http://jabber.org/protocol/rsm');
|
||||
Strophe.addNamespace('SID', 'urn:xmpp:sid:0');
|
||||
@ -484,7 +485,7 @@
|
||||
// Waiting time of less then one second means features aren't used.
|
||||
return;
|
||||
}
|
||||
_converse.idle_seconds = 0;
|
||||
_converse.idle_seconds = 0
|
||||
_converse.auto_changed_status = false; // Was the user's status changed by _converse.js?
|
||||
window.addEventListener('click', _converse.onUserActivity);
|
||||
window.addEventListener('focus', _converse.onUserActivity);
|
||||
|
@ -1204,12 +1204,12 @@
|
||||
*/
|
||||
this.showSpinner();
|
||||
this.model.checkForReservedNick(
|
||||
this.onNickNameFound.bind(this),
|
||||
this.onNickNameNotFound.bind(this)
|
||||
this.onReservedNicknameFound.bind(this),
|
||||
this.onReservedNicknameNotFound.bind(this)
|
||||
)
|
||||
},
|
||||
|
||||
onNickNameFound (iq) {
|
||||
onReservedNicknameFound (iq) {
|
||||
/* We've received an IQ response from the server which
|
||||
* might contain the user's reserved nickname.
|
||||
* If no nickname is found we either render a form for
|
||||
@ -1228,7 +1228,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
onNickNameNotFound (message) {
|
||||
onReservedNicknameNotFound (message) {
|
||||
const nick = this.getDefaultNickName();
|
||||
if (nick) {
|
||||
this.join(nick);
|
||||
|
@ -113,6 +113,7 @@
|
||||
allow_muc_invitations: true,
|
||||
auto_join_on_invite: false,
|
||||
auto_join_rooms: [],
|
||||
auto_register_muc_nickname: false,
|
||||
muc_domain: undefined,
|
||||
muc_history_max_stanzas: undefined,
|
||||
muc_instant_rooms: true,
|
||||
@ -184,6 +185,8 @@
|
||||
|
||||
initialize() {
|
||||
this.constructor.__super__.initialize.apply(this, arguments);
|
||||
this.on('change:connection_status', this.onConnectionStatusChanged, this);
|
||||
|
||||
this.occupants = new _converse.ChatRoomOccupants();
|
||||
this.occupants.browserStorage = new Backbone.BrowserStorage.session(
|
||||
b64_sha1(`converse.occupants-${_converse.bare_jid}${this.get('jid')}`)
|
||||
@ -192,6 +195,18 @@
|
||||
this.registerHandlers();
|
||||
},
|
||||
|
||||
async onConnectionStatusChanged () {
|
||||
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED &&
|
||||
_converse.auto_register_muc_nickname &&
|
||||
this.get('reserved_nick')) {
|
||||
|
||||
const result = await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'));
|
||||
if (result.length) {
|
||||
this.registerNickname()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
registerHandlers () {
|
||||
/* Register presence and message handlers for this chat
|
||||
* groupchat
|
||||
@ -798,6 +813,45 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
async registerNickname () {
|
||||
try {
|
||||
await _converse.api.sendIQ(
|
||||
$iq({
|
||||
'from': _converse.bare_jid,
|
||||
'to': this.get('jid'),
|
||||
'type': 'get'
|
||||
}).c('query', {'xmlns': Strophe.NS.MUC_REGISTER})
|
||||
);
|
||||
} catch (e) {
|
||||
if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')} which does not exist.`);
|
||||
} else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`You're not allowed to register in the groupchat ${this.get('jid')}`);
|
||||
}
|
||||
return _converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
try {
|
||||
await _converse.api.sendIQ($iq({
|
||||
'from': _converse.bare_jid,
|
||||
'to': this.get('jid'),
|
||||
'type': 'set'
|
||||
}).c('query', {'xmlns': Strophe.NS.MUC_REGISTER})
|
||||
.c('x', {'xmlns': Strophe.NS.XFORM, 'type': 'submit'})
|
||||
.c('field', {'var': 'FORM_TYPE'}).c('value').t('http://jabber.org/protocol/muc#register').up().up()
|
||||
.c('field', {'var': 'muc#register_roomnick'}).c('value').t(this.get('nick'))
|
||||
);
|
||||
} catch (e) {
|
||||
if (sizzle('conflict[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it's already taken.`);
|
||||
} else if (sizzle('service-unavailable[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, it doesn't support registration.`);
|
||||
} else if (sizzle('bad-request[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', e).length) {
|
||||
_converse.log(`Can't register nickname ${this.get('nick')} in the groupchat ${this.get('jid')}, invalid data form supplied.`);
|
||||
}
|
||||
return _converse.log(e, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
},
|
||||
|
||||
updateOccupantsOnPresence (pres) {
|
||||
/* Given a presence stanza, update the occupant model
|
||||
* based on its contents.
|
||||
@ -1259,6 +1313,25 @@
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRegistrationForm (room_jid, user_jid) {
|
||||
_converse.api.sendIQ(
|
||||
$iq({
|
||||
'from': user_jid,
|
||||
'to': room_jid,
|
||||
'type': 'get'
|
||||
}).c('query', {'xmlns': Strophe.NS.REGISTER})
|
||||
).then(iq => {
|
||||
|
||||
}).catch(iq => {
|
||||
if (sizzle('item-not-found[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]', iq).length) {
|
||||
this.feedback.set('error', __(`Error: the groupchat ${this.model.getDisplayName()} does not exist.`));
|
||||
} else if (sizzle('not-allowed[xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"]').length) {
|
||||
this.feedback.set('error', __(`Sorry, you're not allowed to registerd in this groupchat`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/************************ BEGIN Event Handlers ************************/
|
||||
_converse.on('addClientFeatures', () => {
|
||||
if (_converse.allow_muc) {
|
||||
|
19
src/templates/chatroom_registration_modal.html
Normal file
19
src/templates/chatroom_registration_modal.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="modal fade" id="room-registration-modal" tabindex="-1" role="dialog" aria-labelledby="room-registration-modal-label" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="room-registration-modal-label">{{{o.display_name}}}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="{{{o.label_close}}}"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="converse-form">
|
||||
{[ if (o.feedback.get('error')) { ]} <div class="alert alert-danger" role="alert">{{{o.feedback.get('error')}}}</div> {[ } ]}
|
||||
{[ if (!o.feedback.get('error')) { ]} <span class="spinner fa fa-spinner"></span> {[ } ]}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{{o.__('Close')}}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -202,6 +202,7 @@ var specs = [
|
||||
"spec/user-details-modal",
|
||||
"spec/messages",
|
||||
"spec/chatroom",
|
||||
"spec/room_registration",
|
||||
"spec/autocomplete",
|
||||
"spec/minchats",
|
||||
"spec/notification",
|
||||
|
Loading…
Reference in New Issue
Block a user