UNPKG

@jsxc/jsxc

Version:

Real-time XMPP chat application with video calls, file transfer and encrypted communication

129 lines (99 loc) 4.19 kB
import Log from '../../../util/Log'; import JID from '../../../JID'; import { IContact } from '../../../Contact.interface'; import { TYPE as NOTICETYPE, FUNCTION as NOTICEFUNCTION } from '../../../Notice'; import Roster from '../../../ui/Roster'; import { Presence } from '../../AbstractConnection'; import 'jquery'; import AbstractHandler from '../AbstractHandler'; import { ContactSubscription as SUBSCRIPTION } from '../../../Contact.interface'; const PRESENCE = { ERROR: 'error', SUBSCRIBE: 'subscribe', UNAVAILABLE: 'unavailable', UNSUBSCRIBED: 'unsubscribed', }; export default class extends AbstractHandler { public processStanza(stanza: Element): boolean { Log.debug('onPresence', stanza); let presence = { type: $(stanza).attr('type'), from: new JID($(stanza).attr('from')), show: $(stanza).find('show').text(), status: $(stanza).find('status').text(), }; let status: Presence = this.determinePresenceStatus(presence); if (presence.from.bare === this.account.getJID().bare) { if (presence.from.resource === this.account.getJID().resource) { this.account.setPresence(status); } return this.PRESERVE_HANDLER; } if (presence.type === PRESENCE.ERROR) { let errorStanza = $(stanza).find('error'); let errorCode = errorStanza.attr('code') || ''; let errorType = errorStanza.attr('type') || ''; let errorBy = errorStanza.attr('by') || 'unkown'; let errorReason = errorStanza.find('>:first-child').prop('tagName'); let errorText = errorStanza.find('text').text(); if (errorStanza.find('remote-server-not-found').length > 0) { Log.info( `You have an invalid contact (${presence.from.toString()}) in your contact list. The error message from ${errorBy} is: ${errorText}` ); } else { Log.error('[XMPP] ' + errorType + ', ' + errorCode + ', ' + errorReason + ', ' + errorText); } return this.PRESERVE_HANDLER; } let contact = this.account.getContact(presence.from); // incoming friendship request if (presence.type === PRESENCE.SUBSCRIBE) { Log.debug('received subscription request'); this.processSubscribtionRequest(presence.from, contact); return this.PRESERVE_HANDLER; } if (typeof contact === 'undefined') { Log.warn('Could not find contact object for ' + presence.from.full); return this.PRESERVE_HANDLER; } let oldPresence = contact.getPresence(); contact.setStatus(presence.status); contact.setPresence(presence.from.resource, status); contact.setResource(''); // reset jid, so new messages go to the bare jid Log.debug('Presence (' + presence.from.full + '): ' + Presence[status]); this.account.triggerPresenceHook(contact, contact.getPresence(), oldPresence); // preserve handler return this.PRESERVE_HANDLER; } private processSubscribtionRequest(jid: JID, contact: IContact) { if (contact) { Log.debug('Auto approve contact request, because he is already in our contact list.'); this.account.getConnection().getRosterService().sendSubscriptionAnswer(contact.getJid(), true); if (contact.getSubscription() !== SUBSCRIPTION.TO) { Roster.get().add(contact); } return this.PRESERVE_HANDLER; } this.account.getNoticeManager().addNotice({ title: 'Friendship_request', description: 'from ' + jid.bare, type: NOTICETYPE.contact, fnName: NOTICEFUNCTION.contactRequest, fnParams: [jid.bare], }); } private determinePresenceStatus(presence): Presence { let status; if (presence.type === PRESENCE.UNAVAILABLE || presence.type === PRESENCE.UNSUBSCRIBED) { status = Presence.offline; } else { let show = presence.show; if (show === '') { status = Presence.online; } else { status = Presence[show]; } } return status; } }