ソースを参照

fix(auth): creating valet tokens for shared subscription users (#895)

* fix(auth): creating valet tokens for shared subscription users

* fix(auth): updating storage quota
Karol Sójko 1 年間 前
コミット
b48eeb16c3

+ 12 - 11
packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.ts

@@ -12,6 +12,7 @@ import { GetRegularSubscriptionForUser } from '../GetRegularSubscriptionForUser/
 import { GetSharedSubscriptionForUser } from '../GetSharedSubscriptionForUser/GetSharedSubscriptionForUser'
 import { GetSubscriptionSetting } from '../GetSubscriptionSetting/GetSubscriptionSetting'
 import { SettingName } from '@standardnotes/domain-core'
+import { UserSubscription } from '../../Subscription/UserSubscription'
 
 export class CreateValetToken implements UseCaseInterface {
   constructor(
@@ -27,8 +28,17 @@ export class CreateValetToken implements UseCaseInterface {
   async execute(dto: CreateValetTokenDTO): Promise<CreateValetTokenResponseData> {
     const { userUuid, ...payload } = dto
 
+    let sharedSubscription: UserSubscription | undefined
+    const sharedSubscriptionOrError = await this.getSharedSubscription.execute({
+      userUuid,
+    })
+    if (!sharedSubscriptionOrError.isFailed()) {
+      sharedSubscription = sharedSubscriptionOrError.getValue()
+    }
+
     const regularSubscriptionOrError = await this.getRegularSubscription.execute({
-      userUuid: dto.userUuid,
+      userUuid: sharedSubscription ? undefined : dto.userUuid,
+      subscriptionId: sharedSubscription ? (sharedSubscription.subscriptionId as number) : undefined,
     })
     if (regularSubscriptionOrError.isFailed()) {
       return {
@@ -77,22 +87,13 @@ export class CreateValetToken implements UseCaseInterface {
       uploadBytesLimit = +(overwriteWithUserUploadBytesLimitSetting.setting.props.value as string)
     }
 
-    let sharedSubscriptionUuid = undefined
-    const sharedSubscriptionOrError = await this.getSharedSubscription.execute({
-      userUuid,
-    })
-    if (!sharedSubscriptionOrError.isFailed()) {
-      const sharedSubscription = sharedSubscriptionOrError.getValue()
-      sharedSubscriptionUuid = sharedSubscription.uuid
-    }
-
     const tokenData: ValetTokenData = {
       userUuid: dto.userUuid,
       permittedOperation: dto.operation,
       permittedResources: dto.resources,
       uploadBytesUsed,
       uploadBytesLimit,
-      sharedSubscriptionUuid,
+      sharedSubscriptionUuid: sharedSubscription ? sharedSubscription.uuid : undefined,
       regularSubscriptionUuid: regularSubscription.uuid,
     }
 

+ 28 - 1
packages/auth/src/Domain/UseCase/GetRegularSubscriptionForUser/GetRegularSubscriptionForUser.spec.ts

@@ -35,7 +35,7 @@ describe('GetRegularSubscriptionForUser', () => {
     expect(result.isFailed()).toBe(true)
   })
 
-  it('returns regular subscription when user subscription is regular', async () => {
+  it('returns regular subscription for user uuid', async () => {
     const useCase = createUseCase()
 
     const result = await useCase.execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
@@ -43,4 +43,31 @@ describe('GetRegularSubscriptionForUser', () => {
     expect(result.isFailed()).toBe(false)
     expect(result.getValue()).toBe(regularSubscription)
   })
+
+  it('returns regular subscription for shared subscription id', async () => {
+    const useCase = createUseCase()
+    userSubscriptionRepository.findBySubscriptionIdAndType = jest.fn().mockResolvedValue([regularSubscription])
+
+    const result = await useCase.execute({ subscriptionId: 1 })
+
+    expect(result.isFailed()).toBe(false)
+    expect(result.getValue()).toBe(regularSubscription)
+  })
+
+  it('returns error if subscription for shared subscription id is not found', async () => {
+    const useCase = createUseCase()
+    userSubscriptionRepository.findBySubscriptionIdAndType = jest.fn().mockResolvedValue([])
+
+    const result = await useCase.execute({ subscriptionId: 1 })
+
+    expect(result.isFailed()).toBe(true)
+  })
+
+  it('returns error if no parameters are specified', async () => {
+    const useCase = createUseCase()
+
+    const result = await useCase.execute({})
+
+    expect(result.isFailed()).toBe(true)
+  })
 })

+ 24 - 1
packages/auth/src/Domain/UseCase/GetRegularSubscriptionForUser/GetRegularSubscriptionForUser.ts

@@ -9,7 +9,18 @@ export class GetRegularSubscriptionForUser implements UseCaseInterface<UserSubsc
   constructor(private userSubscriptionRepository: UserSubscriptionRepositoryInterface) {}
 
   async execute(dto: GetRegularSubscriptionForUserDTO): Promise<Result<UserSubscription>> {
-    const userUuidOrError = Uuid.create(dto.userUuid)
+    if (dto.userUuid !== undefined) {
+      return this.getRegularSubscriptionForUser(dto.userUuid)
+    }
+    if (dto.subscriptionId !== undefined) {
+      return this.getRegularSubscriptionForSharedSubscription(dto.subscriptionId)
+    }
+
+    return Result.fail('Invalid parameters.')
+  }
+
+  private async getRegularSubscriptionForUser(userUuidString: string): Promise<Result<UserSubscription>> {
+    const userUuidOrError = Uuid.create(userUuidString)
     if (userUuidOrError.isFailed()) {
       return Result.fail(`Could not get regular subscription for user: ${userUuidOrError.getError()}`)
     }
@@ -25,4 +36,16 @@ export class GetRegularSubscriptionForUser implements UseCaseInterface<UserSubsc
 
     return Result.ok(userSubscription)
   }
+
+  private async getRegularSubscriptionForSharedSubscription(subscriptionId: number): Promise<Result<UserSubscription>> {
+    const userSubscription = await this.userSubscriptionRepository.findBySubscriptionIdAndType(
+      subscriptionId,
+      UserSubscriptionType.Regular,
+    )
+    if (userSubscription.length === 0) {
+      return Result.fail(`User subscription for shared subscription ${subscriptionId} not found.`)
+    }
+
+    return Result.ok(userSubscription[0])
+  }
 }

+ 2 - 1
packages/auth/src/Domain/UseCase/GetRegularSubscriptionForUser/GetRegularSubscriptionForUserDTO.ts

@@ -1,3 +1,4 @@
 export interface GetRegularSubscriptionForUserDTO {
-  userUuid: string
+  userUuid?: string
+  subscriptionId?: number
 }

+ 11 - 9
packages/auth/src/Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser.ts

@@ -31,9 +31,19 @@ export class UpdateStorageQuotaUsedForUser implements UseCaseInterface<void> {
       return Result.fail(`Could not find user with uuid: ${userUuid.value}`)
     }
 
-    const regularSubscriptionOrError = await this.getRegularSubscription.execute({
+    const sharedSubscriptionOrError = await this.getSharedSubscription.execute({
       userUuid: user.uuid,
     })
+    let sharedSubscription: UserSubscription | undefined
+    if (!sharedSubscriptionOrError.isFailed()) {
+      sharedSubscription = sharedSubscriptionOrError.getValue()
+      await this.updateUploadBytesUsedSetting(sharedSubscription, dto.bytesUsed)
+    }
+
+    const regularSubscriptionOrError = await this.getRegularSubscription.execute({
+      userUuid: sharedSubscription ? undefined : user.uuid,
+      subscriptionId: sharedSubscription ? (sharedSubscription.subscriptionId as number) : undefined,
+    })
     if (regularSubscriptionOrError.isFailed()) {
       return Result.fail(`Could not find regular user subscription for user with uuid: ${userUuid.value}`)
     }
@@ -41,14 +51,6 @@ export class UpdateStorageQuotaUsedForUser implements UseCaseInterface<void> {
 
     await this.updateUploadBytesUsedSetting(regularSubscription, dto.bytesUsed)
 
-    const sharedSubscriptionOrError = await this.getSharedSubscription.execute({
-      userUuid: user.uuid,
-    })
-    if (!sharedSubscriptionOrError.isFailed()) {
-      const sharedSubscription = sharedSubscriptionOrError.getValue()
-      await this.updateUploadBytesUsedSetting(sharedSubscription, dto.bytesUsed)
-    }
-
     return Result.ok()
   }