Files
DiceCloud/app/imports/api/sharing/sharing.js
2021-08-10 19:01:31 +02:00

133 lines
3.9 KiB
JavaScript

import SimpleSchema from 'simpl-schema';
import { assertOwnership } from '/imports/api/sharing/sharingPermissions.js';
import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js';
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
import { RefSchema } from '/imports/api/parenting/ChildSchema.js';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { getUserTier } from '/imports/api/users/patreon/tiers.js';
const setPublic = new ValidatedMethod({
name: 'sharing.setPublic',
validate: new SimpleSchema({
docRef: RefSchema,
isPublic: { type: Boolean },
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
run({docRef, isPublic}){
let doc = fetchDocByRef(docRef);
assertOwnership(doc, this.userId);
return getCollectionByName(docRef.collection).update(docRef.id, {
$set: {public: isPublic},
});
},
});
const updateUserSharePermissions = new ValidatedMethod({
name: 'sharing.updateUserSharePermissions',
validate: new SimpleSchema({
docRef: RefSchema,
userId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
role: {
type: String,
allowedValues: ['reader', 'writer', 'none'],
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
run({docRef, userId, role}){
let doc = fetchDocByRef(docRef);
if (role === 'none'){
// only assert ownership if you aren't removing yourself
if (this.userId !== userId){
assertOwnership(doc, this.userId);
}
return getCollectionByName(docRef.collection).update(docRef.id, {
$pullAll: { readers: userId, writers: userId },
});
}
if (doc.owner === userId){
throw new Meteor.Error('Sharing update failed',
'User is already the owner of this document');
}
assertOwnership(doc, this.userId);
if (role === 'reader'){
return getCollectionByName(docRef.collection).update(docRef.id, {
$addToSet: { readers: userId },
$pullAll: { writers: userId },
});
} else if (role === 'writer'){
return getCollectionByName(docRef.collection).update(docRef.id, {
$addToSet: { writers: userId },
$pullAll: { readers: userId },
});
}
},
});
const transferOwnership = new ValidatedMethod({
name: 'sharing.transferOwnership',
validate: new SimpleSchema({
docRef: RefSchema,
userId: {
type: String,
regEx: SimpleSchema.RegEx.Id,
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
run({docRef, userId}){
let doc = fetchDocByRef(docRef);
assertOwnership(doc, this.userId);
let collection = getCollectionByName(docRef.collection);
let tier = getUserTier(userId);
if (docRef.collection === 'creatures'){
let currentCharacterCount = collection.find({
owner: userId,
}, {
fields: {_id: 1},
}).count();
if (
tier.characterSlots !== -1 &&
currentCharacterCount >= tier.characterSlots
){
throw new Meteor.Error('Sharing.methods.transferOwnership.denied',
'The new owner is already at their character limit')
}
} else if (docRef.collection === 'libraries'){
if (!tier.paidBenefits){
throw new Meteor.Error('Sharing.methods.transferOwnership.denied',
'The new owner\'s Patreon tier does not have access to library ownership');
}
}
// First remove current permissions for the user
collection.update(docRef.id, {
$pullAll: { writers: userId, readers: userId },
});
// Then make the user the owner and the current owner a writer
return collection.update(docRef.id, {
$set: {owner: userId},
$addToSet: { writers: this.userId },
});
},
});
export { setPublic, updateUserSharePermissions, transferOwnership };