mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
fix existing opted in users not being able to be granted with the feature after increasing the limit
This commit is contained in:
parent
8e2e36aa62
commit
3df0ffc5d3
3 changed files with 40 additions and 26 deletions
|
|
@ -39,6 +39,7 @@ export const optInFeatureResolver = authorized<
|
|||
errorCodes: [OptInFeatureErrorCode.NotFound],
|
||||
}
|
||||
}
|
||||
log.info('Opted in to a feature', optIn)
|
||||
|
||||
const token = signFeatureToken(optIn, claims.uid)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { IsNull, Not } from 'typeorm'
|
|||
import { Feature } from '../entity/feature'
|
||||
import { getRepository } from '../entity/utils'
|
||||
import { env } from '../env'
|
||||
import { AppDataSource } from '../server'
|
||||
import { logger } from '../utils/logger'
|
||||
|
||||
export enum FeatureName {
|
||||
|
|
@ -29,6 +30,7 @@ const optInUltraRealisticVoice = async (uid: string): Promise<Feature> => {
|
|||
where: {
|
||||
user: { id: uid },
|
||||
name: FeatureName.UltraRealisticVoice,
|
||||
grantedAt: Not(IsNull()),
|
||||
},
|
||||
relations: ['user'],
|
||||
})
|
||||
|
|
@ -39,22 +41,31 @@ const optInUltraRealisticVoice = async (uid: string): Promise<Feature> => {
|
|||
}
|
||||
|
||||
// opt in to feature for the first 1000 users
|
||||
const count = await getRepository(Feature).countBy({
|
||||
name: FeatureName.UltraRealisticVoice,
|
||||
grantedAt: Not(IsNull()),
|
||||
})
|
||||
const newFeatures = (await AppDataSource.query(
|
||||
`insert into omnivore.features (user_id, name, granted_at)
|
||||
select $1, $2, $3 from omnivore.features
|
||||
where name = $2 and granted_at is not null
|
||||
having count(*) < 1000
|
||||
on conflict (user_id, name)
|
||||
do update set granted_at = $3
|
||||
returning *, granted_at as "grantedAt", created_at as "createdAt", updated_at as "updatedAt";`,
|
||||
[uid, FeatureName.UltraRealisticVoice, new Date()]
|
||||
)) as Feature[]
|
||||
|
||||
let grantedAt: Date | null = new Date()
|
||||
if (count >= 1000) {
|
||||
logger.info('feature limit reached')
|
||||
grantedAt = null
|
||||
// if no new features were created then user has exceeded max users
|
||||
if (newFeatures.length === 0) {
|
||||
logger.info('exceeded max users')
|
||||
|
||||
return getRepository(Feature).save({
|
||||
user: { id: uid },
|
||||
name: FeatureName.UltraRealisticVoice,
|
||||
grantedAt: null,
|
||||
})
|
||||
}
|
||||
|
||||
return getRepository(Feature).save({
|
||||
user: { id: uid },
|
||||
name: FeatureName.UltraRealisticVoice,
|
||||
grantedAt,
|
||||
})
|
||||
logger.info('opted in', { uid, feature: newFeatures[0] })
|
||||
|
||||
return newFeatures[0]
|
||||
}
|
||||
|
||||
export const signFeatureToken = (
|
||||
|
|
@ -64,6 +75,8 @@ export const signFeatureToken = (
|
|||
},
|
||||
userId: string
|
||||
): string => {
|
||||
logger.info('signing feature token', { grantedAt: feature.grantedAt })
|
||||
|
||||
return jwt.sign(
|
||||
{
|
||||
uid: userId,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import 'mocha'
|
||||
import { expect } from 'chai'
|
||||
import * as jwt from 'jsonwebtoken'
|
||||
import 'mocha'
|
||||
import sinon, { SinonFakeTimers } from 'sinon'
|
||||
import { Feature } from '../../src/entity/feature'
|
||||
import { User } from '../../src/entity/user'
|
||||
import { getRepository } from '../../src/entity/utils'
|
||||
import { env } from '../../src/env'
|
||||
import { createTestUser, deleteTestUser } from '../db'
|
||||
import { graphqlRequest, request } from '../util'
|
||||
import { getRepository } from '../../src/entity/utils'
|
||||
import { Feature } from '../../src/entity/feature'
|
||||
import * as jwt from 'jsonwebtoken'
|
||||
import sinon, { SinonFakeTimers } from 'sinon'
|
||||
import { env } from '../../src/env'
|
||||
import { Like } from 'typeorm'
|
||||
|
||||
xdescribe('features resolvers', () => {
|
||||
describe('features resolvers', () => {
|
||||
let loginUser: User
|
||||
let authToken: string
|
||||
|
||||
|
|
@ -25,7 +24,7 @@ xdescribe('features resolvers', () => {
|
|||
})
|
||||
|
||||
after(async () => {
|
||||
await deleteTestUser(loginUser.name)
|
||||
await deleteTestUser(loginUser.id)
|
||||
})
|
||||
|
||||
describe('optInFeature API', () => {
|
||||
|
|
@ -96,6 +95,8 @@ xdescribe('features resolvers', () => {
|
|||
})
|
||||
|
||||
context('when user is not the first 1000 users', () => {
|
||||
let users: User[]
|
||||
|
||||
before(async () => {
|
||||
// create 1000 opt-in users
|
||||
const usersToSave = Array.from(Array(1000).keys()).map((i) => {
|
||||
|
|
@ -109,7 +110,7 @@ xdescribe('features resolvers', () => {
|
|||
}
|
||||
})
|
||||
|
||||
const users = await getRepository(User).save(usersToSave)
|
||||
users = await getRepository(User).save(usersToSave)
|
||||
|
||||
const features = users.map((user) => {
|
||||
return {
|
||||
|
|
@ -124,9 +125,8 @@ xdescribe('features resolvers', () => {
|
|||
|
||||
after(async () => {
|
||||
// reset opt-in users
|
||||
await getRepository(User).delete({
|
||||
name: Like(`opt-in-user-%`),
|
||||
})
|
||||
Promise.all(users.map((user) => deleteTestUser(user.id)))
|
||||
// reset feature
|
||||
await getRepository(Feature).delete({
|
||||
name: featureName,
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue