mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #2414 from overleaf/ta-features-overrides
Persistent Features Override GitOrigin-RevId: 9bb389458a4fde3cc36dbc5b8c3f7185b7e4e9bf
This commit is contained in:
parent
86352c58be
commit
a493ec94b2
4 changed files with 117 additions and 3 deletions
|
@ -50,6 +50,9 @@ const FeaturesUpdater = {
|
|||
},
|
||||
samlFeatures(cb) {
|
||||
return FeaturesUpdater._getSamlFeatures(user_id, cb)
|
||||
},
|
||||
featuresOverrides(cb) {
|
||||
return FeaturesUpdater._getFeaturesOverrides(user_id, cb)
|
||||
}
|
||||
}
|
||||
return async.series(jobs, function(err, results) {
|
||||
|
@ -67,7 +70,8 @@ const FeaturesUpdater = {
|
|||
institutionFeatures,
|
||||
v1Features,
|
||||
bonusFeatures,
|
||||
samlFeatures
|
||||
samlFeatures,
|
||||
featuresOverrides
|
||||
} = results
|
||||
logger.log(
|
||||
{
|
||||
|
@ -77,7 +81,8 @@ const FeaturesUpdater = {
|
|||
institutionFeatures,
|
||||
v1Features,
|
||||
bonusFeatures,
|
||||
samlFeatures
|
||||
samlFeatures,
|
||||
featuresOverrides
|
||||
},
|
||||
'merging user features'
|
||||
)
|
||||
|
@ -86,7 +91,8 @@ const FeaturesUpdater = {
|
|||
institutionFeatures,
|
||||
v1Features,
|
||||
bonusFeatures,
|
||||
samlFeatures
|
||||
samlFeatures,
|
||||
featuresOverrides
|
||||
])
|
||||
const features = _.reduce(
|
||||
featureSets,
|
||||
|
@ -143,6 +149,36 @@ const FeaturesUpdater = {
|
|||
})
|
||||
},
|
||||
|
||||
_getFeaturesOverrides(user_id, callback) {
|
||||
UserGetter.getUser(user_id, { featuresOverrides: 1 }, (error, user) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (
|
||||
!user ||
|
||||
!user.featuresOverrides ||
|
||||
user.featuresOverrides.length === 0
|
||||
) {
|
||||
return callback(null, {})
|
||||
}
|
||||
let activeFeaturesOverrides = []
|
||||
for (let featuresOverride of user.featuresOverrides) {
|
||||
if (
|
||||
!featuresOverride.expiresAt ||
|
||||
featuresOverride.expiresAt > new Date()
|
||||
) {
|
||||
activeFeaturesOverrides.push(featuresOverride.features)
|
||||
}
|
||||
}
|
||||
const features = _.reduce(
|
||||
activeFeaturesOverrides,
|
||||
FeaturesUpdater._mergeFeatures,
|
||||
{}
|
||||
)
|
||||
return callback(null, features)
|
||||
})
|
||||
},
|
||||
|
||||
_getV1Features(user_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, features) {}
|
||||
|
|
|
@ -91,6 +91,32 @@ const UserSchema = new Schema({
|
|||
default: Settings.defaultFeatures.referencesSearch
|
||||
}
|
||||
},
|
||||
featuresOverrides: [
|
||||
{
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default() {
|
||||
return new Date()
|
||||
}
|
||||
},
|
||||
expiresAt: { type: Date },
|
||||
note: { type: String },
|
||||
features: {
|
||||
collaborators: { type: Number },
|
||||
versioning: { type: Boolean },
|
||||
dropbox: { type: Boolean },
|
||||
github: { type: Boolean },
|
||||
gitBridge: { type: Boolean },
|
||||
compileTimeout: { type: Number },
|
||||
compileGroup: { type: String },
|
||||
templates: { type: Boolean },
|
||||
trackChanges: { type: Boolean },
|
||||
mendeley: { type: Boolean },
|
||||
zotero: { type: Boolean },
|
||||
referencesSearch: { type: Boolean }
|
||||
}
|
||||
}
|
||||
],
|
||||
// when auto-merged from SL and must-reconfirm is set, we may end up using
|
||||
// `sharelatexHashedPassword` to recover accounts...
|
||||
sharelatexHashedPassword: String,
|
||||
|
|
|
@ -338,4 +338,51 @@ describe('FeatureUpdater.refreshFeatures', function() {
|
|||
)
|
||||
}) // returns a promise
|
||||
})
|
||||
|
||||
describe('when the user has features overrides', function() {
|
||||
beforeEach(function() {
|
||||
const futureDate = new Date()
|
||||
futureDate.setDate(futureDate.getDate() + 1)
|
||||
return User.update(
|
||||
{
|
||||
_id: this.user._id
|
||||
},
|
||||
{
|
||||
featuresOverrides: [
|
||||
{
|
||||
features: {
|
||||
github: true
|
||||
}
|
||||
},
|
||||
{
|
||||
features: {
|
||||
dropbox: true
|
||||
},
|
||||
expiresAt: new Date(1990, 12, 25)
|
||||
},
|
||||
{
|
||||
features: {
|
||||
trackChanges: true
|
||||
},
|
||||
expiresAt: futureDate
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}) // returns a promise
|
||||
|
||||
it('should set their features to the overridden set', function(done) {
|
||||
return syncUserAndGetFeatures(this.user, (error, features) => {
|
||||
if (error != null) {
|
||||
throw error
|
||||
}
|
||||
let expectedFeatures = Object.assign(settings.defaultFeatures, {
|
||||
github: true,
|
||||
trackChanges: true
|
||||
})
|
||||
expect(features).to.deep.equal(expectedFeatures)
|
||||
return done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -142,6 +142,11 @@ class User {
|
|||
UserModel.update({ _id: this.id }, update, callback)
|
||||
}
|
||||
|
||||
setFeaturesOverride(featuresOverride, callback) {
|
||||
const update = { $push: { featuresOverrides: featuresOverride } }
|
||||
UserModel.update({ _id: this.id }, update, callback)
|
||||
}
|
||||
|
||||
setOverleafId(overleafId, callback) {
|
||||
UserModel.update({ _id: this.id }, { 'overleaf.id': overleafId }, callback)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue