<commit_before>import { Meteor } from 'meteor/meteor';

import Comments from '/imports/models/comments';
import Books from '/imports/models/books';

export default class AnnotationService {
	constructor(props) {
		this.token = props.token;
		this.user = Meteor.users.findOne({
			'services.resume.loginTokens.hashedToken': Accounts._hashLoginToken(props.token),
		});
	}

	hasAnnotationPermission(chapterUrl) {
		const book = Books.findOne({'chapters.url': chapterUrl});
		const authorizedBooks = this.user.canAnnotateBooks || [];
		return !!(this.user && (book || ~authorizedBooks.indexOf(book._id)));
	}

	hasAnnotationRevisionPermission(annotationId) {
		const comment = Comments.findOne({_id: annotationId, users: this.user._id});
		return !!comment;
	}

	rewriteRevision(revision) {
		if (revision instanceof Array) {
			const newRevision = [];
			revision.map(singleRevision => {
				newRevision.push({
					tenantId: singleRevision.tenantId,
					text: singleRevision.text,
					created: new Date(),
					updated: new Date()
				});
			});
			return newRevision;
		}
		return {
			tenantId: revision.tenantId,
			text: revision.text,
			created: new Date(),
			updated: new Date()
		};
	}

	createAnnotation(annotation) {
		const newAnnotation = annotation;
		newAnnotation.revisions = this.rewriteRevision(annotation.revisions);

		if (this.hasAnnotationPermission(annotation.bookChapterUrl)) {
			const commentId = Comments.insert({...newAnnotation});
			return Comments.findOne(commentId);
		}
		return new Error('Not authorized');
	}

	deleteAnnotation(annotationId) {
		const annotation = Comments.findOne(annotationId);
		if (this.hasAnnotationPermission(annotation.bookChapterUrl)) {
			return Comments.remove({_id: annotationId});
		}
		return new Error('Not authorized');
	}

	addRevision(annotationId, revision) {
		const newRevision = this.rewriteRevision(revision);
		if (this.hasAnnotationRevisionPermission(annotationId)) {
			return Comments.update({_id: annotationId}, {
				$addToSet: {
					revisions: newRevision
				}
			});
		}
		return new Error('Not authorized');
	}
}<commit_msg>add admin permissions to annotation mutations<commit_after>import { Meteor } from 'meteor/meteor';

import Comments from '/imports/models/comments';
import Books from '/imports/models/books';

import AdminService from './adminService';

export default class AnnotationService extends AdminService {
	constructor(props) {
		super(props);
		this.token = props.token;
		this.user = Meteor.users.findOne({
			'services.resume.loginTokens.hashedToken': Accounts._hashLoginToken(props.token),
		});
	}

	hasAnnotationPermission(chapterUrl) {
		const book = Books.findOne({'chapters.url': chapterUrl});
		const authorizedBooks = this.user.canAnnotateBooks || [];
		if (book) {
			return !!(this.user && ~authorizedBooks.indexOf(book._id));
		} 
		return false;
	}

	hasAnnotationRevisionPermission(annotationId) {
		const comment = Comments.findOne({_id: annotationId, users: this.user._id});
		return !!comment;
	}

	rewriteRevision(revision) {
		if (revision instanceof Array) {
			const newRevision = [];
			revision.map(singleRevision => {
				newRevision.push({
					tenantId: singleRevision.tenantId,
					text: singleRevision.text,
					created: new Date(),
					updated: new Date()
				});
			});
			return newRevision;
		}
		return {
			tenantId: revision.tenantId,
			text: revision.text,
			created: new Date(),
			updated: new Date()
		};
	}

	createAnnotation(annotation) {
		const newAnnotation = annotation;
		newAnnotation.revisions = this.rewriteRevision(annotation.revisions);

		if (this.hasAnnotationPermission(annotation.bookChapterUrl) || this.userIsAdmin) {
			const commentId = Comments.insert({...newAnnotation});
			return Comments.findOne(commentId);
		}
		return new Error('Not authorized');
	}

	deleteAnnotation(annotationId) {
		const annotation = Comments.findOne(annotationId);
		if (this.hasAnnotationPermission(annotation.bookChapterUrl) || this.userIsAdmin) {
			return Comments.remove({_id: annotationId});
		}
		return new Error('Not authorized');
	}

	addRevision(annotationId, revision) {
		const newRevision = this.rewriteRevision(revision);
		if (this.hasAnnotationRevisionPermission(annotationId) || this.userIsAdmin) {
			return Comments.update({_id: annotationId}, {
				$addToSet: {
					revisions: newRevision
				}
			});
		}
		return new Error('Not authorized');
	}
}
{'fraction_non_alphanumeric': 0.12717809459153653, 'fraction_numerical': 0.0, 'mean_word_length': 4.5181023720349565, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5982019', 'n_tokens_mistral': 1554, 'n_tokens_neox': 1310, 'n_words': 264}