mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Async await entity providers (#28841)
* fix: async await entity providers * fix: async await userMembershipGetters * fix: move to export class style for UserMembershipsHandler * fix: update how Publisher model returns its v1 values GitOrigin-RevId: f94bcb81c9703deaf938cdf7dff31c6e24dc4bd8
This commit is contained in:
committed by
Copybot
parent
9b6eab9251
commit
7f3c8a281d
@@ -1,4 +1,4 @@
|
||||
import { promisify, callbackify } from 'node:util'
|
||||
import { callbackify } from 'node:util'
|
||||
import UserGetter from '../User/UserGetter.mjs'
|
||||
import UserMembershipsHandler from '../UserMembership/UserMembershipsHandler.mjs'
|
||||
import UserMembershipEntityConfigs from '../UserMembership/UserMembershipEntityConfigs.mjs'
|
||||
@@ -55,39 +55,36 @@ async function getCurrentInstitutionsWithLicence(userId) {
|
||||
return Object.values(institutions)
|
||||
}
|
||||
|
||||
async function getConfirmedAffiliations(userId) {
|
||||
const emailsData = await UserGetter.promises.getUserFullEmails(userId)
|
||||
|
||||
const confirmedAffiliations = emailsData
|
||||
.filter(
|
||||
emailData =>
|
||||
emailData.confirmedAt &&
|
||||
emailData.affiliation &&
|
||||
emailData.affiliation.institution &&
|
||||
emailData.affiliation.institution.confirmed
|
||||
)
|
||||
.map(emailData => emailData.affiliation)
|
||||
|
||||
return confirmedAffiliations
|
||||
}
|
||||
|
||||
async function getManagedInstitutions(userId) {
|
||||
return await UserMembershipsHandler.promises.getEntitiesByUser(
|
||||
UserMembershipEntityConfigs.institution,
|
||||
userId
|
||||
)
|
||||
}
|
||||
|
||||
const InstitutionsGetter = {
|
||||
getConfirmedAffiliations(userId, callback) {
|
||||
UserGetter.getUserFullEmails(userId, function (error, emailsData) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
|
||||
const confirmedAffiliations = emailsData
|
||||
.filter(
|
||||
emailData =>
|
||||
emailData.confirmedAt &&
|
||||
emailData.affiliation &&
|
||||
emailData.affiliation.institution &&
|
||||
emailData.affiliation.institution.confirmed
|
||||
)
|
||||
.map(emailData => emailData.affiliation)
|
||||
|
||||
callback(null, confirmedAffiliations)
|
||||
})
|
||||
},
|
||||
|
||||
getConfirmedAffiliations: callbackify(getConfirmedAffiliations),
|
||||
getCurrentInstitutionIds: callbackify(getCurrentInstitutionIds),
|
||||
getCurrentInstitutionsWithLicence: callbackify(
|
||||
getCurrentInstitutionsWithLicence
|
||||
),
|
||||
|
||||
getManagedInstitutions(userId, callback) {
|
||||
UserMembershipsHandler.getEntitiesByUser(
|
||||
UserMembershipEntityConfigs.institution,
|
||||
userId,
|
||||
callback
|
||||
)
|
||||
},
|
||||
getManagedInstitutions: callbackify(getManagedInstitutions),
|
||||
}
|
||||
|
||||
InstitutionsGetter.promises = {
|
||||
@@ -95,7 +92,7 @@ InstitutionsGetter.promises = {
|
||||
getCurrentInstitutionIds,
|
||||
getCurrentInstitutionsWithLicence,
|
||||
getCurrentAndPastAffiliationIds,
|
||||
getManagedInstitutions: promisify(InstitutionsGetter.getManagedInstitutions),
|
||||
getManagedInstitutions,
|
||||
}
|
||||
|
||||
export default InstitutionsGetter
|
||||
|
||||
@@ -1,17 +1,4 @@
|
||||
/* eslint-disable
|
||||
n/handle-callback-err,
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
import async from 'async'
|
||||
|
||||
import { promisifyAll } from '@overleaf/promise-utils'
|
||||
import { callbackifyAll } from '@overleaf/promise-utils'
|
||||
import UserMembershipEntityConfigs from './UserMembershipEntityConfigs.mjs'
|
||||
import * as InstitutionModel from '../../models/Institution.mjs'
|
||||
import * as SubscriptionModel from '../../models/Subscription.mjs'
|
||||
@@ -25,11 +12,25 @@ const EntityModels = {
|
||||
}
|
||||
|
||||
const UserMembershipsHandler = {
|
||||
removeUserFromAllEntities(userId, callback) {
|
||||
// get all writable entity types
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
async getEntitiesByUser(entityConfig, userId) {
|
||||
if (!Features.hasFeature('saas')) {
|
||||
return []
|
||||
}
|
||||
const query = entityConfig.baseQuery || {}
|
||||
query[entityConfig.fields.access] = userId
|
||||
|
||||
const entities =
|
||||
(await EntityModels[entityConfig.modelName].find(query)) || []
|
||||
|
||||
const filledEntities = []
|
||||
for (const entity of entities) {
|
||||
const filled = await entity.fetchV1DataPromise()
|
||||
filledEntities.push(filled)
|
||||
}
|
||||
return filledEntities
|
||||
},
|
||||
|
||||
async removeUserFromAllEntities(userId) {
|
||||
const entityConfigs = []
|
||||
for (const key in UserMembershipEntityConfigs) {
|
||||
const entityConfig = UserMembershipEntityConfigs[key]
|
||||
@@ -39,52 +40,19 @@ const UserMembershipsHandler = {
|
||||
}
|
||||
|
||||
// remove the user from all entities types
|
||||
async.map(
|
||||
entityConfigs,
|
||||
(entityConfig, innerCallback) =>
|
||||
UserMembershipsHandler.removeUserFromEntities(
|
||||
entityConfig,
|
||||
userId,
|
||||
innerCallback
|
||||
),
|
||||
callback
|
||||
)
|
||||
for (const entityConfig of entityConfigs) {
|
||||
await UserMembershipsHandler.removeUserFromEntities(entityConfig, userId)
|
||||
}
|
||||
},
|
||||
|
||||
removeUserFromEntities(entityConfig, userId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
async removeUserFromEntities(entityConfig, userId) {
|
||||
const removeOperation = { $pull: {} }
|
||||
removeOperation.$pull[entityConfig.fields.write] = userId
|
||||
EntityModels[entityConfig.modelName]
|
||||
.updateMany({}, removeOperation)
|
||||
.then(result => callback(null, result))
|
||||
.catch(callback)
|
||||
},
|
||||
|
||||
getEntitiesByUser(entityConfig, userId, callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
if (!Features.hasFeature('saas')) return callback(null, [])
|
||||
const query = Object.assign({}, entityConfig.baseQuery)
|
||||
query[entityConfig.fields.access] = userId
|
||||
EntityModels[entityConfig.modelName]
|
||||
.find(query)
|
||||
.then(entities => {
|
||||
if (entities == null) {
|
||||
entities = []
|
||||
}
|
||||
async.mapSeries(
|
||||
entities,
|
||||
(entity, cb) => entity.fetchV1Data(cb),
|
||||
callback
|
||||
)
|
||||
})
|
||||
.catch(callback)
|
||||
await EntityModels[entityConfig.modelName].updateMany({}, removeOperation)
|
||||
},
|
||||
}
|
||||
|
||||
UserMembershipsHandler.promises = promisifyAll(UserMembershipsHandler)
|
||||
export default UserMembershipsHandler
|
||||
export default {
|
||||
...callbackifyAll(UserMembershipsHandler),
|
||||
promises: UserMembershipsHandler,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import mongoose from '../infrastructure/Mongoose.mjs'
|
||||
import settings from '@overleaf/settings'
|
||||
import logger from '@overleaf/logger'
|
||||
import { promisify } from '@overleaf/promise-utils'
|
||||
import { callbackify } from '@overleaf/promise-utils'
|
||||
import { fetchJson } from '@overleaf/fetch-utils'
|
||||
const { Schema } = mongoose
|
||||
const { ObjectId } = Schema
|
||||
@@ -20,16 +20,15 @@ export const InstitutionSchema = new Schema(
|
||||
)
|
||||
|
||||
// fetch institution's data from v1 API. Errors are ignored
|
||||
InstitutionSchema.method('fetchV1Data', async function (callback) {
|
||||
async function fetchV1DataPromise() {
|
||||
const url = `${settings.apis.v1.url}/universities/list/${this.v1Id}`
|
||||
try {
|
||||
const parsedBody = await fetchJson(url)
|
||||
this.name = parsedBody != null ? parsedBody.name : undefined
|
||||
this.countryCode = parsedBody != null ? parsedBody.country_code : undefined
|
||||
this.departments = parsedBody != null ? parsedBody.departments : undefined
|
||||
this.portalSlug = parsedBody != null ? parsedBody.portal_slug : undefined
|
||||
this.enterpriseCommons =
|
||||
parsedBody != null ? parsedBody.enterprise_commons : undefined
|
||||
this.name = parsedBody?.name
|
||||
this.countryCode = parsedBody?.country_code
|
||||
this.departments = parsedBody?.departments
|
||||
this.portalSlug = parsedBody?.portal_slug
|
||||
this.enterpriseCommons = parsedBody?.enterprise_commons
|
||||
} catch (error) {
|
||||
// log error and carry on without v1 data
|
||||
logger.err(
|
||||
@@ -37,12 +36,11 @@ InstitutionSchema.method('fetchV1Data', async function (callback) {
|
||||
'[fetchV1DataError]'
|
||||
)
|
||||
}
|
||||
callback(null, this)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
InstitutionSchema.method(
|
||||
'fetchV1DataPromise',
|
||||
promisify(InstitutionSchema.methods.fetchV1Data)
|
||||
)
|
||||
InstitutionSchema.method('fetchV1DataPromise', fetchV1DataPromise)
|
||||
|
||||
InstitutionSchema.method('fetchV1Data', callbackify(fetchV1DataPromise))
|
||||
|
||||
export const Institution = mongoose.model('Institution', InstitutionSchema)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import mongoose from '../infrastructure/Mongoose.mjs'
|
||||
import settings from '@overleaf/settings'
|
||||
import logger from '@overleaf/logger'
|
||||
import request from 'request'
|
||||
import { fetchJson } from '@overleaf/fetch-utils'
|
||||
import { callbackify } from '@overleaf/promise-utils'
|
||||
const { Schema } = mongoose
|
||||
const { ObjectId } = Schema
|
||||
|
||||
@@ -13,37 +14,32 @@ export const PublisherSchema = new Schema(
|
||||
{ minimize: false }
|
||||
)
|
||||
|
||||
// fetch publisher's (brand on v1) data from v1 API. Errors are ignored
|
||||
PublisherSchema.method('fetchV1Data', function (callback) {
|
||||
request(
|
||||
{
|
||||
baseUrl: settings.apis.v1.url,
|
||||
url: `/api/v2/brands/${this.slug}`,
|
||||
method: 'GET',
|
||||
auth: {
|
||||
async function fetchV1DataPromise() {
|
||||
const url = `${settings.apis.v1.url}/api/v2/brands/${this.slug}`
|
||||
try {
|
||||
const parsedBody = await fetchJson(url, {
|
||||
basicAuth: {
|
||||
user: settings.apis.v1.user,
|
||||
pass: settings.apis.v1.pass,
|
||||
sendImmediately: true,
|
||||
},
|
||||
timeout: settings.apis.v1.timeout,
|
||||
},
|
||||
(error, response, body) => {
|
||||
let parsedBody
|
||||
try {
|
||||
parsedBody = JSON.parse(body)
|
||||
} catch (error1) {
|
||||
// log error and carry on without v1 data
|
||||
error = error1
|
||||
logger.err(
|
||||
{ model: 'Publisher', slug: this.slug, error },
|
||||
'[fetchV1DataError]'
|
||||
)
|
||||
}
|
||||
this.name = parsedBody != null ? parsedBody.name : undefined
|
||||
this.partner = parsedBody != null ? parsedBody.partner : undefined
|
||||
callback(null, this)
|
||||
}
|
||||
)
|
||||
})
|
||||
signal: AbortSignal.timeout(settings.apis.v1.timeout),
|
||||
})
|
||||
|
||||
this.name = parsedBody?.name
|
||||
this.partner = parsedBody?.partner
|
||||
return this
|
||||
} catch (error) {
|
||||
// log error and carry on without v1 data
|
||||
logger.err(
|
||||
{ model: 'Publisher', slug: this.slug, error },
|
||||
'[fetchV1DataError]'
|
||||
)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
PublisherSchema.method('fetchV1DataPromise', fetchV1DataPromise)
|
||||
|
||||
PublisherSchema.method('fetchV1Data', callbackify(fetchV1DataPromise))
|
||||
|
||||
export const Publisher = mongoose.model('Publisher', PublisherSchema)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import mongoose from '../infrastructure/Mongoose.mjs'
|
||||
import { TeamInviteSchema } from './TeamInvite.mjs'
|
||||
import { callbackify } from '@overleaf/promise-utils'
|
||||
|
||||
const { Schema } = mongoose
|
||||
const { ObjectId } = Schema
|
||||
@@ -123,8 +124,11 @@ export const SubscriptionSchema = new Schema(
|
||||
)
|
||||
|
||||
// Subscriptions have no v1 data to fetch
|
||||
SubscriptionSchema.method('fetchV1Data', function (callback) {
|
||||
callback(null, this)
|
||||
})
|
||||
async function fetchV1DataPromise() {
|
||||
return this
|
||||
}
|
||||
SubscriptionSchema.method('fetchV1Data', callbackify(fetchV1DataPromise))
|
||||
|
||||
SubscriptionSchema.method('fetchV1DataPromise', fetchV1DataPromise)
|
||||
|
||||
export const Subscription = mongoose.model('Subscription', SubscriptionSchema)
|
||||
|
||||
Reference in New Issue
Block a user