Removed all patreon based restrictions
This commit is contained in:
@@ -74,41 +74,6 @@ Schemas.User = new SimpleSchema({
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
patreon: {
|
||||
type: Object,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.accessToken": {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.refreshToken": {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.tokenExpiryDate": {
|
||||
type: Date,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.userId": {
|
||||
type: String,
|
||||
optional: true,
|
||||
index: 1,
|
||||
},
|
||||
"patreon.entitledCents": {
|
||||
type: Number,
|
||||
decimal: false,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.entitledCentsOverride": {
|
||||
type: Number,
|
||||
decimal: false,
|
||||
optional: true,
|
||||
},
|
||||
"patreon.error": {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
Meteor.users.attachSchema(Schemas.User);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
Template.registerHelper("isTier5", function(){
|
||||
let user = Meteor.user();
|
||||
if (!user) return false;
|
||||
patreon = user.patreon;
|
||||
if (!patreon) return false;
|
||||
return patreon.entitledCents >= 300 || patreon.entitledCentsOverride >= 300;
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
import { format as formatUrl } from 'url';
|
||||
|
||||
const CLIENT_ID = Meteor.settings &&
|
||||
Meteor.settings.public.patreon &&
|
||||
Meteor.settings.public.patreon.clientId;
|
||||
|
||||
Template.registerHelper("patreonLoginUrl", function() {
|
||||
if (!CLIENT_ID) {
|
||||
console.warn('Could not find Meteor.settings.public.patreon.clientId to make patreon link')
|
||||
return;
|
||||
}
|
||||
return formatUrl({
|
||||
protocol: 'https',
|
||||
host: 'patreon.com',
|
||||
pathname: '/oauth2/authorize',
|
||||
query: {
|
||||
response_type: 'code',
|
||||
client_id: CLIENT_ID,
|
||||
redirect_uri: Meteor.absoluteUrl() + 'patreon-redirect',
|
||||
state: Meteor.userId(),
|
||||
scope: 'identity',
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -34,9 +34,6 @@
|
||||
<a href="/account" style="text-decoration: underline; cursor: pointer; font-size: 16px;">
|
||||
{{profileLink}}
|
||||
</a>
|
||||
<a href="/account" style="text-decoration: underline; cursor: pointer; font-size: 16px; margin-left: 8px;">
|
||||
{{patreonTier}} tier
|
||||
</a>
|
||||
{{else}}
|
||||
<a href="/sign-in" style="text-decoration: underline; cursor: pointer; font-size: 16px;">
|
||||
Sign in
|
||||
@@ -60,7 +57,7 @@
|
||||
<a href="/library" tabindex="-1">
|
||||
<paper-icon-item id="libary">
|
||||
<iron-icon icon="book" item-icon></iron-icon>
|
||||
Libraries (beta)
|
||||
Item Libraries
|
||||
</paper-icon-item>
|
||||
</a>
|
||||
<a href="/guide" tabindex="-1">
|
||||
|
||||
@@ -27,20 +27,6 @@ Template.appDrawer.helpers({
|
||||
let post = PatreonPosts.findOne({}, {sort: {date: -1}});
|
||||
return (post && post.link) || 'https://www.patreon.com/dicecloud';
|
||||
},
|
||||
patreonTier: function(){
|
||||
let user = Meteor.user();
|
||||
if (!user) return;
|
||||
patreon = user.patreon;
|
||||
if (!patreon) return "free";
|
||||
let entitledCents = patreon.entitledCents || 0;
|
||||
if (patreon.entitledCentsOverride > entitledCents){
|
||||
return "$" + (patreon.entitledCentsOverride / 100).toFixed(0);
|
||||
} else if (!patreon.entitledCents){
|
||||
return "free";
|
||||
} else {
|
||||
return "$" + (patreon.entitledCents / 100).toFixed(0);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let drawerLayout;
|
||||
|
||||
@@ -10,26 +10,22 @@
|
||||
</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
{{#if isTier5}}
|
||||
<div class="flex layout vertical center" style="position: relative; padding: 0 16px;">
|
||||
<paper-material class="card" style="padding: 32px; max-width: 800px; width: 100%;">
|
||||
{{#each library in libraries}}
|
||||
<a href="/library/{{library._id}}" tabindex="-1">
|
||||
<paper-item class="library" data-id="{{library._id}}">
|
||||
<paper-item-body>
|
||||
<div>{{library.name}}</div>
|
||||
</paper-item-body>
|
||||
</paper-item>
|
||||
</a>
|
||||
{{/each}}
|
||||
</paper-material>
|
||||
</div>
|
||||
<div class="floatyButton">
|
||||
<paper-fab id="addLibrary" icon="add"></paper-fab>
|
||||
{{#simpleTooltip}}Add Library{{/simpleTooltip}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{> patronsOnly }}
|
||||
{{/if}}
|
||||
<div class="flex layout vertical center" style="position: relative; padding: 0 16px;">
|
||||
<paper-material class="card" style="padding: 32px; max-width: 800px; width: 100%;">
|
||||
{{#each library in libraries}}
|
||||
<a href="/library/{{library._id}}" tabindex="-1">
|
||||
<paper-item class="library" data-id="{{library._id}}">
|
||||
<paper-item-body>
|
||||
<div>{{library.name}}</div>
|
||||
</paper-item-body>
|
||||
</paper-item>
|
||||
</a>
|
||||
{{/each}}
|
||||
</paper-material>
|
||||
</div>
|
||||
<div class="floatyButton">
|
||||
<paper-fab id="addLibrary" icon="add"></paper-fab>
|
||||
{{#simpleTooltip}}Add Library{{/simpleTooltip}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -8,49 +8,43 @@
|
||||
<div class="flex layout horizontal center" style="height: 40px; margin-left: 8px;">
|
||||
{{name}}
|
||||
</div>
|
||||
{{#if isTier5}}{{#if canUserEdit}}
|
||||
{{#if canUserEdit}}
|
||||
<paper-icon-button icon="settings" id="edit"></paper-icon-button>
|
||||
{{/if}}{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div bottom-item class="layout horizontal center">
|
||||
<paper-input label="Search" class="search-input">
|
||||
<iron-icon icon="search" prefix></iron-icon>
|
||||
</paper-input>
|
||||
<div class="flex"></div>
|
||||
{{#if canUserSubscribe}}
|
||||
<paper-button style="color: rgba(255,255,255,0.87);" id="subscribe">
|
||||
<iron-icon icon="add-circle"></iron-icon>
|
||||
Subscribe
|
||||
</paper-button>
|
||||
{{else if canUserUnsubscribe}}
|
||||
<paper-button style="color: rgba(255,255,255,0.87);" id="unsubscribe">
|
||||
<iron-icon icon="remove-circle"></iron-icon>
|
||||
Unsubscribe
|
||||
</paper-button>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if isTier5}}
|
||||
<div bottom-item class="layout horizontal center">
|
||||
<paper-input label="Search" class="search-input">
|
||||
<iron-icon icon="search" prefix></iron-icon>
|
||||
</paper-input>
|
||||
<div class="flex"></div>
|
||||
{{#if canUserSubscribe}}
|
||||
<paper-button style="color: rgba(255,255,255,0.87);" id="subscribe">
|
||||
<iron-icon icon="add-circle"></iron-icon>
|
||||
Subscribe
|
||||
</paper-button>
|
||||
{{else if canUserUnsubscribe}}
|
||||
<paper-button style="color: rgba(255,255,255,0.87);" id="unsubscribe">
|
||||
<iron-icon icon="remove-circle"></iron-icon>
|
||||
Unsubscribe
|
||||
</paper-button>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
{{#if isTier5}}
|
||||
<div class="flex layout vertical center" style="position: relative; padding: 0 16px;">
|
||||
<paper-material class="card" style="padding: 32px; max-width: 800px; width: 100%;">
|
||||
{{#each items}}
|
||||
<paper-item data-id={{_id}} class="item">
|
||||
<paper-item-body>
|
||||
<div>{{displayName}}</div>
|
||||
</paper-item-body>
|
||||
</paper-item>
|
||||
{{/each}}
|
||||
</paper-material>
|
||||
</div>
|
||||
<div class="floatyButton">
|
||||
<paper-fab id="addLibraryItem" icon="add"></paper-fab>
|
||||
{{#simpleTooltip}}Add Library Item{{/simpleTooltip}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{> patronsOnly }}
|
||||
{{/if}}
|
||||
<div class="flex layout vertical center" style="position: relative; padding: 0 16px;">
|
||||
<paper-material class="card" style="padding: 32px; max-width: 800px; width: 100%;">
|
||||
{{#each items}}
|
||||
<paper-item data-id={{_id}} class="item">
|
||||
<paper-item-body>
|
||||
<div>{{displayName}}</div>
|
||||
</paper-item-body>
|
||||
</paper-item>
|
||||
{{/each}}
|
||||
</paper-material>
|
||||
</div>
|
||||
<div class="floatyButton">
|
||||
<paper-fab id="addLibraryItem" icon="add"></paper-fab>
|
||||
{{#simpleTooltip}}Add Library Item{{/simpleTooltip}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<template name="patronsOnly">
|
||||
<div class="flex layout vertical center" style="position: relative; padding: 0 16px;">
|
||||
<paper-material class="card" style="padding: 32px; max-width: 800px; width: 100%;">
|
||||
<h3>
|
||||
This beta feature is available to Patreon Insiders who pledge $5 or more
|
||||
</h3>
|
||||
<div class="layout vertical center">
|
||||
<a href="https://www.patreon.com/join/dicecloud/checkout?rid=3002853">
|
||||
<paper-button raised> Become a Patron </paper-button>
|
||||
</a>
|
||||
<a href="{{patreonLoginUrl}}">
|
||||
<paper-button class="connectPatreon" style="color: #d13b2e; margin-top: 12px;">
|
||||
Connect Patreon account
|
||||
</paper-button>
|
||||
</a>
|
||||
</div>
|
||||
<p style="margin-top: 32px;">
|
||||
With the Item Libraries beta you can create collections of items to use
|
||||
across your characters, and share them with other players.
|
||||
</p>
|
||||
<p>
|
||||
You can also subscribe to existing community libraries of items, saving
|
||||
time and effort manually entering item details.
|
||||
</p>
|
||||
</paper-material>
|
||||
</div>
|
||||
</template>
|
||||
@@ -62,28 +62,6 @@
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Patreon
|
||||
</td>
|
||||
{{#if patreon.accessToken}}
|
||||
<td>
|
||||
{{tier}} tier
|
||||
</td>
|
||||
<td>
|
||||
<paper-icon-button icon="refresh" class="refreshPatreon">
|
||||
</paper-icon-button>
|
||||
</td>
|
||||
{{else}}
|
||||
<td>
|
||||
<a href="{{patreonLoginUrl}}">
|
||||
<paper-button raised class="connectPatreon">
|
||||
Connect Patreon account
|
||||
</paper-button>
|
||||
</a>
|
||||
</td>
|
||||
{{/if}}
|
||||
</tr>
|
||||
</table>
|
||||
<div style="max-width: 250px">
|
||||
{{> atForm state="signIn"}}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Template.profile.onCreated(function(){
|
||||
this.showApiKey = new ReactiveVar(false);
|
||||
this.loadingPatreon = new ReactiveVar(false);
|
||||
});
|
||||
|
||||
Template.profile.helpers({
|
||||
@@ -13,26 +12,6 @@ Template.profile.helpers({
|
||||
showApiKey: function(){
|
||||
return Template.instance().showApiKey.get();
|
||||
},
|
||||
patreon: function(){
|
||||
let user = Meteor.user();
|
||||
return user && user.patreon || {};
|
||||
},
|
||||
tier: function(){
|
||||
let user = Meteor.user();
|
||||
if (!user) return;
|
||||
patreon = user.patreon;
|
||||
if (!patreon) return;
|
||||
let entitledCents = patreon.entitledCents || 0;
|
||||
if (Template.instance().loadingPatreon.get()){
|
||||
return "loading..."
|
||||
} else if (patreon.entitledCentsOverride > entitledCents){
|
||||
return `$ ${(patreon.entitledCentsOverride / 100).toFixed(0)} (overridden)`;
|
||||
} else if (patreon.entitledCents === undefined){
|
||||
return "?";
|
||||
} else {
|
||||
return "$" + (patreon.entitledCents / 100).toFixed(0);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Template.profile.events({
|
||||
@@ -60,10 +39,4 @@ Template.profile.events({
|
||||
Meteor.call("generateMyApiKey");
|
||||
instance.showApiKey.set(true);
|
||||
},
|
||||
"click .refreshPatreon": function(event, instance){
|
||||
instance.loadingPatreon.set(true);
|
||||
Meteor.call("updateMyPatreonDetails", (error) => {
|
||||
instance.loadingPatreon.set(false);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
2200
app/package-lock.json
generated
2200
app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@
|
||||
"core-js": "^2.6.11",
|
||||
"file-saver": "^2.0.2",
|
||||
"meteor-node-stubs": "^0.3.3",
|
||||
"patreon": "^0.4.1",
|
||||
"qrcode": "^1.4.4",
|
||||
"request": "^2.88.2",
|
||||
"source-map-support": "^0.5.19",
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
import request from 'request';
|
||||
|
||||
if (
|
||||
Meteor.settings &&
|
||||
Meteor.settings.public &&
|
||||
Meteor.settings.public.patreon
|
||||
) {
|
||||
const CLIENT_ID = Meteor.settings.public.patreon.clientId;
|
||||
const CLIENT_SECRET = Meteor.settings.patreon.clientSecret;
|
||||
const CREATOR_ACCESS_TOKEN = Meteor.settings.patreon.creatorAccessToken;
|
||||
const CAMPAIGN_ID = Meteor.settings.public.patreon.campaignId;
|
||||
|
||||
// Handle redirects from patreon
|
||||
Router.map(function () {
|
||||
this.route("patreon-redirect", {
|
||||
path: "/patreon-redirect",
|
||||
where: "server",
|
||||
action: function () {
|
||||
let route = this;
|
||||
let userId = route.params.query.state;
|
||||
let singleUseCode = route.params.query.code;
|
||||
requestToken(singleUseCode, Meteor.bindEnvironment((error, response, body) => {
|
||||
// Should return an access token, valid for 1 month, which needs to be
|
||||
// stored and used to make requests on behalf of the user
|
||||
if (error){
|
||||
writePatreonError(userId, error);
|
||||
return;
|
||||
}
|
||||
let token;
|
||||
try {
|
||||
token = JSON.parse(body);
|
||||
writePatreonToken(userId, token);
|
||||
} catch(error) {
|
||||
writePatreonError(userId, error);
|
||||
return;
|
||||
}
|
||||
updateIdentity(token.access_token, userId);
|
||||
}));
|
||||
route.response.writeHead(302, {
|
||||
'Location': Meteor.absoluteUrl() + "account",
|
||||
});
|
||||
route.response.end();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
const requestToken = function(singleUseCode, callback){
|
||||
request({
|
||||
method: "POST",
|
||||
uri: "https://www.patreon.com/api/oauth2/token",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
qs: {
|
||||
code: singleUseCode,
|
||||
grant_type: "authorization_code",
|
||||
client_id: CLIENT_ID,
|
||||
client_secret: CLIENT_SECRET,
|
||||
redirect_uri: Meteor.absoluteUrl() + 'patreon-redirect',
|
||||
},
|
||||
}, callback);
|
||||
}
|
||||
|
||||
const getIdentity = function(accessToken, callback){
|
||||
request({
|
||||
uri: "https://www.patreon.com/api/oauth2/v2/identity",
|
||||
headers:{
|
||||
Authorization: "Bearer " + accessToken,
|
||||
},
|
||||
qs: {
|
||||
'include': 'memberships.currently_entitled_tiers',
|
||||
'fields[tier]': 'amount_cents,title',
|
||||
}
|
||||
}, callback);
|
||||
};
|
||||
|
||||
// Should return a new access token for the user
|
||||
// callback is called with (error, response, body)
|
||||
const refreshAccessToken = Meteor.wrapAsync(function(refreshToken, userId, callback){
|
||||
request({
|
||||
method: "POST",
|
||||
uri: "https://www.patreon.com/api/oauth2/token",
|
||||
qs: {
|
||||
grant_type: "refresh_token",
|
||||
refresh_token: refreshToken,
|
||||
client_id: CLIENT_ID,
|
||||
client_secret: CLIENT_SECRET,
|
||||
}
|
||||
}, Meteor.bindEnvironment((error, response, body) => {
|
||||
// Should return an access token, valid for 1 month, which needs to be
|
||||
// stored and used to make requests on behalf of the user
|
||||
if (error){
|
||||
callback(error)
|
||||
return;
|
||||
}
|
||||
let token;
|
||||
try {
|
||||
token = JSON.parse(body);
|
||||
writePatreonToken(userId, token);
|
||||
callback(undefined, token.access_token);
|
||||
} catch(error) {
|
||||
callback(error);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
const updateIdentity = Meteor.wrapAsync(function(accessToken, userId, callback){
|
||||
getIdentity(accessToken, Meteor.bindEnvironment((error, response, body) => {
|
||||
if (error){
|
||||
writePatreonError(userId, error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let identity = JSON.parse(body);
|
||||
let entitledAmount = 0;
|
||||
if (identity && identity.included){
|
||||
identity.included.forEach(doc => {
|
||||
if (
|
||||
doc.type === 'tier' &&
|
||||
doc.attributes &&
|
||||
doc.attributes.amount_cents > entitledAmount
|
||||
){
|
||||
entitledAmount = doc.attributes.amount_cents;
|
||||
}
|
||||
});
|
||||
}
|
||||
let patreonUserId = identity.data.id;
|
||||
writeEntitledCentsAndId(userId, entitledAmount, patreonUserId);
|
||||
if (callback) callback();
|
||||
} catch(error) {
|
||||
writePatreonError(userId, error);
|
||||
if(callback) callback(error);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
updateMyPatreonDetails(){
|
||||
const userId = this.userId;
|
||||
if (!userId) throw new Meteor.Error("not-logged-in", "You must be logged in to update Patreon details");
|
||||
const user = Meteor.users.findOne(userId, {fields: {patreon: 1}});
|
||||
Meteor.users.update(userId, {$unset: {"patreon.entitledCents": 1}});
|
||||
if (!user.patreon || !user.patreon.accessToken){
|
||||
throw new Meteor.Error("no-patreon-access", "Patreon access token not found for this user");
|
||||
}
|
||||
let accessToken = user.patreon.accessToken;
|
||||
if (user.patreon.tokenExpiryDate < new Date()){
|
||||
// Token expired, refresh it before continuing
|
||||
accessToken = refreshAccessToken(user.patreon.refreshToken, userId);
|
||||
}
|
||||
updateIdentity(accessToken, userId);
|
||||
},
|
||||
});
|
||||
|
||||
const writePatreonToken = function(userId, {
|
||||
access_token, refresh_token, expires_in
|
||||
}){
|
||||
// The expiry date is now plus `expires_in` seconds
|
||||
let expiryDate = new Date();
|
||||
expiryDate.setSeconds(expiryDate.getSeconds() + expires_in);
|
||||
// Expire a day early so we don't accidentally miss it
|
||||
expiryDate.setDate(expiryDate.getDate() - 1);
|
||||
|
||||
// Write
|
||||
Meteor.users.update(userId, {
|
||||
$set: {
|
||||
"patreon.accessToken": access_token,
|
||||
"patreon.refreshToken": refresh_token,
|
||||
"patreon.tokenExpiryDate": expiryDate,
|
||||
},
|
||||
$unset: {
|
||||
"patreon.error": 1,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const writeEntitledCentsAndId = function(userId, amount, patreonUserId){
|
||||
Meteor.users.update(userId, {
|
||||
$set: {
|
||||
"patreon.entitledCents": amount,
|
||||
"patreon.userId": patreonUserId,
|
||||
},
|
||||
$unset: {
|
||||
"patreon.error": 1,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const writePatreonError = function(userId, error){
|
||||
console.error({patreonError: error});
|
||||
Meteor.users.update(userId, {
|
||||
$set: {
|
||||
"patreon.error": error.toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const requestMembers = Meteor.wrapAsync(function(cursor, members, callback){
|
||||
request({
|
||||
uri: `https://www.patreon.com/api/oauth2/v2/campaigns/${CAMPAIGN_ID}/members`,
|
||||
headers:{
|
||||
Authorization: "Bearer " + CREATOR_ACCESS_TOKEN,
|
||||
},
|
||||
qs: {
|
||||
"include": "user",
|
||||
"fields[member]": "currently_entitled_amount_cents",
|
||||
"page[cursor]": cursor,
|
||||
}
|
||||
}, (error, reponse, body) => {
|
||||
if (error){
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
let json = JSON.parse(body);
|
||||
if (json.errors) {
|
||||
callback(json.errors);
|
||||
return;
|
||||
}
|
||||
let newMembers = json.data.map(member => ({
|
||||
id: member.relationships.user.data.id,
|
||||
entitledCents: member.attributes.currently_entitled_amount_cents,
|
||||
}));
|
||||
members.push(...newMembers);
|
||||
let next = json.meta.pagination.cursors && json.meta.pagination.cursors.next;
|
||||
if (next){
|
||||
callback(undefined, next);
|
||||
} else {
|
||||
callback(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const updatePatreonMembersEntitledCents = function(){
|
||||
let next = "";
|
||||
let members = [];
|
||||
do {
|
||||
next = requestMembers(next, members);
|
||||
} while (next)
|
||||
members.forEach(({id, entitledCents}) => {
|
||||
Meteor.users.update({
|
||||
"patreon.userId": id
|
||||
}, {$set: {
|
||||
"patreon.entitledCents":entitledCents,
|
||||
}});
|
||||
});
|
||||
return members;
|
||||
}
|
||||
|
||||
// Method to run a manual update
|
||||
Meteor.methods({
|
||||
updatePatreonMembersEntitledCents(){
|
||||
const user = Meteor.users.findOne(this.userId);
|
||||
if (!user || !_.contains(user.roles, "admin")) throw new Meteor.Error(
|
||||
"permission-error", "You need to be logged in as an admin to run this method"
|
||||
);
|
||||
return updatePatreonMembersEntitledCents();
|
||||
},
|
||||
});
|
||||
|
||||
// Cron job to run the update automatically
|
||||
Meteor.startup(() => {
|
||||
SyncedCron.add({
|
||||
name: "updatePatreonMembersEntitledCents",
|
||||
schedule: function(parser) {
|
||||
return parser.text('every 4 hours');
|
||||
},
|
||||
job: updatePatreonMembersEntitledCents,
|
||||
});
|
||||
})
|
||||
}
|
||||
@@ -7,7 +7,6 @@ Meteor.publish("user", function(){
|
||||
apiKey: 1,
|
||||
librarySubscriptions: 1,
|
||||
lastPatreonPostClicked: 1,
|
||||
patreon: 1,
|
||||
}}),
|
||||
PatreonPosts.find({},{sort: {dateAdded: -1}, limit: 1})
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user