|
| 1 | +import { Meteor } from 'meteor/meteor'; |
| 2 | +import { Random } from 'meteor/random'; |
| 3 | + |
| 4 | +import { hasPermission } from '../../../authorization'; |
| 5 | +import { Notifications } from '../../../notifications'; |
| 6 | +import { Invites, Rooms } from '../../../models'; |
| 7 | + |
| 8 | +function getInviteUrl(invite, roomName) { |
| 9 | + const { rid, hash } = invite; |
| 10 | + |
| 11 | + const host = 'open.rocket.chat'; |
| 12 | + const url = `https://go.rocket.chat/${ roomName }?host=${ host }&rid=${ rid }&path=channel/${ roomName }&token=${ hash }`; |
| 13 | + |
| 14 | + return url; |
| 15 | +} |
| 16 | + |
| 17 | +Meteor.methods({ |
| 18 | + findOrCreateInvite(invite) { |
| 19 | + if (!hasPermission(this.userId, 'create-invite-links')) { |
| 20 | + throw new Meteor.Error('not_authorized'); |
| 21 | + } |
| 22 | + |
| 23 | + if (!invite.rid) { |
| 24 | + throw new Meteor.Error('error-the-field-is-required', 'The field rid is required', { method: 'findOrCreateInvite', field: 'rid' }); |
| 25 | + } |
| 26 | + |
| 27 | + const room = Rooms.findOneById(invite.rid); |
| 28 | + if (!room) { |
| 29 | + throw new Meteor.Error('error-invalid-room', 'The rid field is invalid', { method: 'findOrCreateInvite', field: 'rid' }); |
| 30 | + } |
| 31 | + |
| 32 | + let { days, maxUses } = invite; |
| 33 | + const possibleDays = [0, 1, 7, 15, 30]; |
| 34 | + const possibleUses = [0, 1, 5, 10, 25, 50, 100]; |
| 35 | + |
| 36 | + if (!possibleDays.includes(days)) { |
| 37 | + days = 1; |
| 38 | + } |
| 39 | + |
| 40 | + if (!possibleUses.includes(maxUses)) { |
| 41 | + maxUses = 0; |
| 42 | + } |
| 43 | + |
| 44 | + // Before anything, let's check if there's an existing invite with the same settings for the same channel and user and that has not yet expired. |
| 45 | + const query = { |
| 46 | + rid: invite.rid, |
| 47 | + userId: this.userId, |
| 48 | + days, |
| 49 | + maxUses, |
| 50 | + }; |
| 51 | + |
| 52 | + if (days > 0) { |
| 53 | + query.expires = { |
| 54 | + $gt: new Date(), |
| 55 | + }; |
| 56 | + } |
| 57 | + |
| 58 | + if (maxUses > 0) { |
| 59 | + query.uses = 0; |
| 60 | + } |
| 61 | + |
| 62 | + // If an existing invite was found, return it's hash instead of creating a new one. |
| 63 | + const existing = Invites.find(query).fetch(); |
| 64 | + if (existing && existing.length) { |
| 65 | + return { |
| 66 | + hash: existing[0].hash, |
| 67 | + url: getInviteUrl(existing[0], room.fname), |
| 68 | + days: existing[0].days, |
| 69 | + maxUses: existing[0].maxUses, |
| 70 | + uses: existing[0].uses, |
| 71 | + expires: existing[0].expires, |
| 72 | + }; |
| 73 | + } |
| 74 | + |
| 75 | + const hash = Random.id(); |
| 76 | + |
| 77 | + // insert invite |
| 78 | + const now = new Date(); |
| 79 | + let expires = null; |
| 80 | + if (days > 0) { |
| 81 | + expires = new Date(now); |
| 82 | + expires.setDate(expires.getDate() + days); |
| 83 | + } |
| 84 | + |
| 85 | + const createInvite = { |
| 86 | + hash, |
| 87 | + days, |
| 88 | + maxUses, |
| 89 | + rid: invite.rid, |
| 90 | + userId: this.userId, |
| 91 | + createdAt: now, |
| 92 | + expires, |
| 93 | + uses: 0, |
| 94 | + }; |
| 95 | + |
| 96 | + Invites.create(createInvite); |
| 97 | + |
| 98 | + Notifications.notifyLogged('updateInvites', { invite: createInvite }); |
| 99 | + return { |
| 100 | + hash, |
| 101 | + url: getInviteUrl(createInvite, room.fname), |
| 102 | + days, |
| 103 | + maxUses, |
| 104 | + uses: 0, |
| 105 | + expires, |
| 106 | + }; |
| 107 | + }, |
| 108 | +}); |
0 commit comments