summaryrefslogtreecommitdiffstats
path: root/roles/reverseproxy/files/conversejs/src/headless/plugins/vcard/api.js
blob: 8e2226034aee7ec40e68e544157c5cd88f13bdd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import log from "@converse/headless/log";
import { _converse, api, converse } from "../../core.js";
import { createStanza, getVCard } from './utils.js';

const { dayjs, u } = converse.env;

export default {
    /**
     * The XEP-0054 VCard API
     *
     * This API lets you access and update user VCards
     *
     * @namespace _converse.api.vcard
     * @memberOf _converse.api
     */
    vcard: {
        /**
         * Enables setting new values for a VCard.
         *
         * Sends out an IQ stanza to set the user's VCard and if
         * successful, it updates the {@link _converse.VCard}
         * for the passed in JID.
         *
         * @method _converse.api.vcard.set
         * @param { string } jid The JID for which the VCard should be set
         * @param { object } data A map of VCard keys and values
         * @example
         * let jid = _converse.bare_jid;
         * _converse.api.vcard.set( jid, {
         *     'fn': 'John Doe',
         *     'nickname': 'jdoe'
         * }).then(() => {
         *     // Succes
         * }).catch((e) => {
         *     // Failure, e is your error object
         * }).
         */
        async set (jid, data) {
            if (!jid) {
                throw Error("No jid provided for the VCard data");
            }
            const div = document.createElement('div');
            const vcard_el = u.toStanza(`
                <vCard xmlns="vcard-temp">
                    <FN>${data.fn}</FN>
                    <NICKNAME>${data.nickname}</NICKNAME>
                    <URL>${data.url}</URL>
                    <ROLE>${data.role}</ROLE>
                    <EMAIL><INTERNET/><PREF/><USERID>${data.email}</USERID></EMAIL>
                    <PHOTO>
                        <TYPE>${data.image_type}</TYPE>
                        <BINVAL>${data.image}</BINVAL>
                    </PHOTO>
                </vCard>`, div);
            let result;
            try {
                result = await api.sendIQ(createStanza("set", jid, vcard_el));
            } catch (e) {
                throw (e);
            }
            await api.vcard.update(jid, true);
            return result;
        },

        /**
         * @method _converse.api.vcard.get
         * @param {Model|string} model Either a `Model` instance, or a string JID.
         *     If a `Model` instance is passed in, then it must have either a `jid`
         *     attribute or a `muc_jid` attribute.
         * @param { boolean } [force] A boolean indicating whether the vcard should be
         *     fetched from the server even if it's been fetched before.
         * @returns {promise} A Promise which resolves with the VCard data for a particular JID or for
         *     a `Model` instance which represents an entity with a JID (such as a roster contact,
         *     chat or chatroom occupant).
         *
         * @example
         * const { api } = _converse;
         * api.waitUntil('rosterContactsFetched').then(() => {
         *     api.vcard.get('someone@example.org').then(
         *         (vcard) => {
         *             // Do something with the vcard...
         *         }
         *     );
         * });
         */
         get (model, force) {
            if (typeof model === 'string') {
                return getVCard(model);
            }
            const error_date = model.get('vcard_error');
            const already_tried_today = error_date && dayjs(error_date).isSame(new Date(), "day");
            if (force || !model.get('vcard_updated') && !already_tried_today) {
                const jid = model.get('jid');
                if (!jid) {
                    log.error("No JID to get vcard for");
                }
                return getVCard(jid);
            } else {
                return Promise.resolve({});
            }
        },

        /**
         * Fetches the VCard associated with a particular `Model` instance
         * (by using its `jid` or `muc_jid` attribute) and then updates the model with the
         * returned VCard data.
         *
         * @method _converse.api.vcard.update
         * @param { Model } model A `Model` instance
         * @param { boolean } [force] A boolean indicating whether the vcard should be
         *     fetched again even if it's been fetched before.
         * @returns {promise} A promise which resolves once the update has completed.
         * @example
         * const { api } = _converse;
         * api.waitUntil('rosterContactsFetched').then(async () => {
         *     const chatbox = await api.chats.get('someone@example.org');
         *     api.vcard.update(chatbox);
         * });
         */
        async update (model, force) {
            const data = await this.get(model, force);
            model = typeof model === 'string' ? _converse.vcards.get(model) : model;
            if (!model) {
                log.error(`Could not find a VCard model for ${model}`);
                return;
            }
            if (Object.keys(data).length) {
                delete data['stanza']
                model.save(data);
            }
        }
    }
}