refactor: remove RoleName from @standardnotes/common in favour of @standardnotes/domain-core definition

This commit is contained in:
Karol Sójko 2023-01-19 14:05:48 +01:00
parent 56b600dbdc
commit a95ca05c10
No known key found for this signature in database
GPG key ID: A50543BF560BDEB0
49 changed files with 166 additions and 165 deletions

3
.pnp.cjs generated
View file

@ -2693,7 +2693,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.28.1"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/security", "workspace:packages/security"],\
@ -3399,6 +3399,7 @@ const RAW_RUNTIME_STATE =
["@sentry/node", "npm:7.28.1"],\
["@standardnotes/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/security", "workspace:packages/security"],\

View file

@ -22,7 +22,7 @@
"dependencies": {
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.28.1",
"@standardnotes/common": "workspace:^",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/security": "workspace:*",

View file

@ -1,5 +1,5 @@
import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
@ -76,7 +76,7 @@ export class AuthMiddleware extends BaseMiddleware {
response.locals.freeUser =
decodedToken.roles.length === 1 &&
decodedToken.roles.find((role) => role.name === RoleName.CoreUser) !== undefined
decodedToken.roles.find((role) => role.name === RoleName.NAMES.CoreUser) !== undefined
if (this.crossServiceTokenCacheTTL && !crossServiceTokenFetchedFromCache) {
await this.crossServiceTokenCache.set({

View file

@ -1,5 +1,5 @@
import { CrossServiceTokenData } from '@standardnotes/security'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { NextFunction, Request, Response } from 'express'
import { inject, injectable } from 'inversify'
import { BaseMiddleware } from 'inversify-express-utils'
@ -62,7 +62,7 @@ export class WebSocketAuthMiddleware extends BaseMiddleware {
response.locals.freeUser =
decodedToken.roles.length === 1 &&
decodedToken.roles.find((role) => role.name === RoleName.CoreUser) !== undefined
decodedToken.roles.find((role) => role.name === RoleName.NAMES.CoreUser) !== undefined
response.locals.userUuid = decodedToken.user.uuid
response.locals.roles = decodedToken.roles
} catch (error) {

View file

@ -4,7 +4,7 @@ import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { Logger } from 'winston'
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
describe('ApiGatewayAuthMiddleware', () => {
let tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>
@ -28,7 +28,7 @@ describe('ApiGatewayAuthMiddleware', () => {
roles: [
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
],
})
@ -56,7 +56,7 @@ describe('ApiGatewayAuthMiddleware', () => {
expect(response.locals.roles).toEqual([
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
])

View file

@ -12,7 +12,6 @@ import {
SubscriptionInviteResponse,
SubscriptionServerInterface,
} from '@standardnotes/api'
import { RoleName } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import TYPES from '../Bootstrap/Types'
@ -88,7 +87,7 @@ export class SubscriptionInvitesController implements SubscriptionServerInterfac
inviterEmail: params.inviterEmail as string,
inviterUuid: params.inviterUuid as string,
inviteeIdentifier: params.identifier,
inviterRoles: params.inviterRoles as RoleName[],
inviterRoles: params.inviterRoles as string[],
})
if (result.success) {

View file

@ -1,5 +1,5 @@
import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security'
import { ErrorTag, RoleName } from '@standardnotes/common'
import { ErrorTag } from '@standardnotes/common'
import { SettingName } from '@standardnotes/settings'
import { Request, Response } from 'express'
import { inject } from 'inversify'
@ -101,10 +101,10 @@ export class SubscriptionTokensController extends BaseHttpController {
return <{ uuid: string; email: string }>await this.userProjector.projectSimple(user)
}
private async projectRoles(roles: Array<Role>): Promise<Array<{ uuid: string; name: RoleName }>> {
private async projectRoles(roles: Array<Role>): Promise<Array<{ uuid: string; name: string }>> {
const roleProjections = []
for (const role of roles) {
roleProjections.push(<{ uuid: string; name: RoleName }>await this.roleProjector.projectSimple(role))
roleProjections.push(<{ uuid: string; name: string }>await this.roleProjector.projectSimple(role))
}
return roleProjections

View file

@ -1,6 +1,6 @@
/* istanbul ignore file */
import { JSONString, ProtocolVersion, RoleName, Uuid } from '@standardnotes/common'
import { JSONString, ProtocolVersion, Uuid } from '@standardnotes/common'
import {
AccountDeletionRequestedEvent,
UserEmailChangedEvent,
@ -347,7 +347,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
}
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: RoleName[]): UserRolesChangedEvent {
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: string[]): UserRolesChangedEvent {
return {
type: 'USER_ROLES_CHANGED',
createdAt: this.timer.getUTCDate(),

View file

@ -1,4 +1,4 @@
import { Uuid, RoleName, ProtocolVersion, JSONString } from '@standardnotes/common'
import { Uuid, ProtocolVersion, JSONString } from '@standardnotes/common'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import {
AccountDeletionRequestedEvent,
@ -54,7 +54,7 @@ export interface DomainEventFactoryInterface {
userCreatedAtTimestamp: number
regularSubscriptionUuid: Uuid | undefined
}): AccountDeletionRequestedEvent
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: RoleName[]): UserRolesChangedEvent
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: string[]): UserRolesChangedEvent
createUserEmailChangedEvent(userUuid: string, fromEmail: string, toEmail: string): UserEmailChangedEvent
createUserDisabledSessionUserAgentLoggingEvent(dto: {
userUuid: Uuid

View file

@ -1,7 +1,8 @@
import 'reflect-metadata'
import { Role } from '@standardnotes/security'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { RoleToSubscriptionMapInterface } from '../Role/RoleToSubscriptionMapInterface'
import { User } from '../User/User'
@ -40,10 +41,10 @@ describe('FeatureService', () => {
.fn()
.mockImplementation((subscriptionName: SubscriptionName) => {
if (subscriptionName === SubscriptionName.PlusPlan) {
return RoleName.PlusUser
return RoleName.NAMES.PlusUser
}
if (subscriptionName === SubscriptionName.ProPlan) {
return RoleName.ProUser
return RoleName.NAMES.ProUser
}
return undefined
@ -67,13 +68,13 @@ describe('FeatureService', () => {
}
role1 = {
name: RoleName.PlusUser,
name: RoleName.NAMES.PlusUser,
uuid: 'role-1-1-1',
permissions: Promise.resolve([permission1, permission3]),
} as jest.Mocked<Role>
role2 = {
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
uuid: 'role-2-2-2',
permissions: Promise.resolve([permission2]),
} as jest.Mocked<Role>
@ -223,7 +224,7 @@ describe('FeatureService', () => {
it('should not return user features if those cannot be find for permissions', async () => {
role1 = {
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
uuid: 'role-1-1-1',
permissions: Promise.resolve([permission4]),
} as jest.Mocked<Role>
@ -303,7 +304,7 @@ describe('FeatureService', () => {
} as jest.Mocked<Permission>
const nonSubscriptionRole = {
name: RoleName.FilesBetaUser,
name: RoleName.NAMES.FilesBetaUser,
uuid: 'role-files-beta',
permissions: Promise.resolve([nonSubscriptionPermission]),
} as jest.Mocked<Role>
@ -347,7 +348,7 @@ describe('FeatureService', () => {
.mockReturnValueOnce(SubscriptionName.ProPlan)
role2 = {
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
uuid: 'role-2-2-2',
permissions: Promise.resolve([permission1, permission2]),
} as jest.Mocked<Role>
@ -384,7 +385,7 @@ describe('FeatureService', () => {
subscription2.endsAt = lesserExpireAt
role2 = {
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
uuid: 'role-2-2-2',
permissions: Promise.resolve([permission1, permission2]),
} as jest.Mocked<Role>

View file

@ -1,4 +1,4 @@
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { FeatureDescription, GetFeatures } from '@standardnotes/features'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
@ -117,7 +117,7 @@ export class FeatureService implements FeatureServiceInterface {
...featureForPermission,
expires_at: longestLastingSubscription ? longestLastingSubscription.endsAt : undefined,
no_expire: longestLastingSubscription ? false : true,
role_name: role.name as RoleName,
role_name: role.name,
})
continue

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
@ -39,7 +40,7 @@ describe('SubscriptionExpiredEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
@ -47,7 +48,7 @@ describe('SubscriptionPurchasedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionReassignedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
@ -45,7 +46,7 @@ describe('SubscriptionReassignedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>
@ -137,7 +138,7 @@ describe('SubscriptionReassignedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
},

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
@ -39,7 +40,7 @@ describe('SubscriptionRefundedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import * as dayjs from 'dayjs'
import { Logger } from 'winston'
@ -42,7 +43,7 @@ describe('SubscriptionRenewedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { ContentDecoderInterface, RoleName, SubscriptionName } from '@standardnotes/common'
import { ContentDecoderInterface, SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionSyncRequestedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
@ -55,7 +56,7 @@ describe('SubscriptionSyncRequestedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>
@ -144,7 +145,7 @@ describe('SubscriptionSyncRequestedEventHandler', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
uuid: '123',

View file

@ -4,7 +4,8 @@ import { Logger } from 'winston'
import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { RoleRepositoryInterface } from '../Role/RoleRepositoryInterface'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { Role } from '../Role/Role'
import { ClientServiceInterface } from '../Client/ClientServiceInterface'
@ -39,7 +40,7 @@ describe('RoleService', () => {
beforeEach(() => {
basicRole = {
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
permissions: Promise.resolve([
{
name: PermissionName.MarkdownBasicEditor,
@ -48,7 +49,7 @@ describe('RoleService', () => {
} as jest.Mocked<Role>
proRole = {
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
permissions: Promise.resolve([
{
name: PermissionName.DailyEmailBackup,
@ -62,7 +63,7 @@ describe('RoleService', () => {
roleRepository.findOneByName = jest.fn().mockReturnValue(proRole)
roleToSubscriptionMap = {} as jest.Mocked<RoleToSubscriptionMapInterface>
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(RoleName.ProUser)
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(RoleName.NAMES.ProUser)
offlineUserSubscription = {
endsAt: 100,
@ -97,7 +98,7 @@ describe('RoleService', () => {
it('should add role to user', async () => {
await createService().addUserRole(user, SubscriptionName.ProPlan)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.NAMES.ProUser)
user.roles = Promise.resolve([basicRole, proRole])
expect(userRepository.save).toHaveBeenCalledWith(user)
})
@ -113,7 +114,7 @@ describe('RoleService', () => {
await createService().addUserRole(user, SubscriptionName.ProPlan)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.NAMES.ProUser)
expect(userRepository.save).toHaveBeenCalledWith(user)
expect(await user.roles).toHaveLength(2)
})
@ -142,7 +143,7 @@ describe('RoleService', () => {
it('should set offline role to offline subscription', async () => {
await createService().setOfflineUserRole(offlineUserSubscription)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.ProUser)
expect(roleRepository.findOneByName).toHaveBeenCalledWith(RoleName.NAMES.ProUser)
expect(offlineUserSubscriptionRepository.save).toHaveBeenCalledWith({
endsAt: 100,
cancelled: false,

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { RoleToSubscriptionMap } from './RoleToSubscriptionMap'
import { Role } from './Role'
@ -9,11 +10,11 @@ describe('RoleToSubscriptionMap', () => {
const createMap = () => new RoleToSubscriptionMap()
it('should return subscription name for role name', () => {
expect(createMap().getSubscriptionNameForRoleName(RoleName.ProUser)).toEqual(SubscriptionName.ProPlan)
expect(createMap().getSubscriptionNameForRoleName(RoleName.NAMES.ProUser)).toEqual(SubscriptionName.ProPlan)
})
it('should return role name for subscription name', () => {
expect(createMap().getRoleNameForSubscriptionName(SubscriptionName.PlusPlan)).toEqual(RoleName.PlusUser)
expect(createMap().getRoleNameForSubscriptionName(SubscriptionName.PlusPlan)).toEqual(RoleName.NAMES.PlusUser)
})
it('should not return role name for subscription name that does not exist', () => {
@ -23,21 +24,21 @@ describe('RoleToSubscriptionMap', () => {
it('should filter our non subscription roles from an array of roles', () => {
const roles = [
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
} as jest.Mocked<Role>,
{
name: RoleName.FilesBetaUser,
name: RoleName.NAMES.FilesBetaUser,
} as jest.Mocked<Role>,
{
name: RoleName.PlusUser,
name: RoleName.NAMES.PlusUser,
} as jest.Mocked<Role>,
]
expect(createMap().filterNonSubscriptionRoles(roles)).toEqual([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
{
name: RoleName.FilesBetaUser,
name: RoleName.NAMES.FilesBetaUser,
},
])
})
@ -45,18 +46,18 @@ describe('RoleToSubscriptionMap', () => {
it('should filter our subscription roles from an array of roles', () => {
const roles = [
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
} as jest.Mocked<Role>,
{
name: RoleName.FilesBetaUser,
name: RoleName.NAMES.FilesBetaUser,
} as jest.Mocked<Role>,
{
name: RoleName.PlusUser,
name: RoleName.NAMES.PlusUser,
} as jest.Mocked<Role>,
]
expect(createMap().filterSubscriptionRoles(roles)).toEqual([
{
name: RoleName.PlusUser,
name: RoleName.NAMES.PlusUser,
},
])
})

View file

@ -1,4 +1,5 @@
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { injectable } from 'inversify'
import { Role } from './Role'
@ -6,26 +7,26 @@ import { RoleToSubscriptionMapInterface } from './RoleToSubscriptionMapInterface
@injectable()
export class RoleToSubscriptionMap implements RoleToSubscriptionMapInterface {
private readonly roleNameToSubscriptionNameMap = new Map<RoleName, SubscriptionName>([
[RoleName.PlusUser, SubscriptionName.PlusPlan],
[RoleName.ProUser, SubscriptionName.ProPlan],
private readonly roleNameToSubscriptionNameMap = new Map<string, SubscriptionName>([
[RoleName.NAMES.PlusUser, SubscriptionName.PlusPlan],
[RoleName.NAMES.ProUser, SubscriptionName.ProPlan],
])
private readonly nonSubscriptionRoles = [RoleName.CoreUser, RoleName.FilesBetaUser]
private readonly nonSubscriptionRoles = [RoleName.NAMES.CoreUser, RoleName.NAMES.FilesBetaUser]
filterNonSubscriptionRoles(roles: Role[]): Array<Role> {
return roles.filter((role) => this.nonSubscriptionRoles.includes(role.name as RoleName))
return roles.filter((role) => this.nonSubscriptionRoles.includes(role.name))
}
filterSubscriptionRoles(roles: Role[]): Array<Role> {
return roles.filter((role) => !this.nonSubscriptionRoles.includes(role.name as RoleName))
return roles.filter((role) => !this.nonSubscriptionRoles.includes(role.name))
}
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined {
getSubscriptionNameForRoleName(roleName: string): SubscriptionName | undefined {
return this.roleNameToSubscriptionNameMap.get(roleName)
}
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): RoleName | undefined {
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): string | undefined {
for (const [roleNameItem, subscriptionNameItem] of this.roleNameToSubscriptionNameMap) {
if (subscriptionNameItem === subscriptionName) {
return roleNameItem

View file

@ -1,9 +1,9 @@
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { Role } from './Role'
export interface RoleToSubscriptionMapInterface {
filterNonSubscriptionRoles(roles: Role[]): Array<Role>
filterSubscriptionRoles(roles: Role[]): Array<Role>
getSubscriptionNameForRoleName(roleName: RoleName): SubscriptionName | undefined
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): RoleName | undefined
getSubscriptionNameForRoleName(roleName: string): SubscriptionName | undefined
getRoleNameForSubscriptionName(subscriptionName: SubscriptionName): string | undefined
}

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionSettingName } from '@standardnotes/settings'
import { PermissionName } from '@standardnotes/features'
@ -20,7 +21,7 @@ describe('SubscriptionSettingsAssociationService', () => {
beforeEach(() => {
roleToSubscriptionMap = {} as jest.Mocked<RoleToSubscriptionMapInterface>
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(RoleName.PlusUser)
roleToSubscriptionMap.getRoleNameForSubscriptionName = jest.fn().mockReturnValue(RoleName.NAMES.PlusUser)
role = {} as jest.Mocked<Role>

View file

@ -1,4 +1,4 @@
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { PermissionName } from '@standardnotes/features'
import { SubscriptionSettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
@ -65,7 +65,7 @@ export class SubscriptionSettingsAssociationService implements SubscriptionSetti
async getFileUploadLimit(subscriptionName: SubscriptionName): Promise<number> {
const roleName = this.roleToSubscriptionMap.getRoleNameForSubscriptionName(subscriptionName)
const role = await this.roleRepository.findOneByName(roleName as RoleName)
const role = await this.roleRepository.findOneByName(roleName as string)
if (role === null) {
throw new Error(`Could not find role with name: ${roleName}`)
}

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { RoleServiceInterface } from '../../Role/RoleServiceInterface'
@ -42,7 +43,7 @@ describe('AcceptSharedSubscriptionInvitation', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,6 +1,6 @@
import 'reflect-metadata'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { SubscriptionTokenRepositoryInterface } from '../../Subscription/SubscriptionTokenRepositoryInterface'
import { User } from '../../User/User'
@ -20,7 +20,7 @@ describe('AuthenticateSubscriptionToken', () => {
subscriptionTokenRepository.getUserUuidByToken = jest.fn().mockReturnValue('1-2-3')
user = {
roles: Promise.resolve([{ name: RoleName.CoreUser }]),
roles: Promise.resolve([{ name: RoleName.NAMES.CoreUser }]),
} as jest.Mocked<User>
userRepository = {} as jest.Mocked<UserRepositoryInterface>

View file

@ -1,6 +1,7 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { RoleServiceInterface } from '../../Role/RoleServiceInterface'
@ -49,7 +50,7 @@ describe('CancelSharedSubscriptionInvitation', () => {
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
]),
} as jest.Mocked<User>

View file

@ -1,4 +1,3 @@
import { RoleName } from '@standardnotes/common'
import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security'
import { inject, injectable } from 'inversify'
@ -78,7 +77,7 @@ export class CreateCrossServiceToken implements UseCaseInterface {
>this.sessionProjector.projectSimple(session)
}
private projectRoles(roles: Array<Role>): Array<{ uuid: string; name: RoleName }> {
return roles.map((role) => <{ uuid: string; name: RoleName }>this.roleProjector.projectSimple(role))
private projectRoles(roles: Array<Role>): Array<{ uuid: string; name: string }> {
return roles.map((role) => <{ uuid: string; name: string }>this.roleProjector.projectSimple(role))
}
}

View file

@ -12,7 +12,7 @@ import { SharedSubscriptionInvitationRepositoryInterface } from '../../SharedSub
import { InviteToSharedSubscription } from './InviteToSharedSubscription'
import { UserSubscriptionRepositoryInterface } from '../../Subscription/UserSubscriptionRepositoryInterface'
import { UserSubscription } from '../../Subscription/UserSubscription'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
import { SharedSubscriptionInvitation } from '../../SharedSubscription/SharedSubscriptionInvitation'
import { InvitationStatus } from '../../SharedSubscription/InvitationStatus'
@ -65,7 +65,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
})
expect(sharedSubscriptionInvitationRepository.save).not.toHaveBeenCalled()
@ -80,7 +80,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.PlusUser],
inviterRoles: [RoleName.NAMES.PlusUser],
}),
).toEqual({
success: false,
@ -100,7 +100,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
}),
).toEqual({
success: false,
@ -117,7 +117,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
})
expect(sharedSubscriptionInvitationRepository.save).toHaveBeenCalledWith({
@ -146,7 +146,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'a75a31ce95365904ef0e0a8e6cefc1f5e99adfef81bbdb6d4499eeb10ae0ff67',
inviterEmail: 'inviter@test.te',
inviterUuid: '1-2-3',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
})
expect(sharedSubscriptionInvitationRepository.save).toHaveBeenCalledWith({
@ -180,7 +180,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
})
expect(sharedSubscriptionInvitationRepository.save).not.toHaveBeenCalled()
@ -200,7 +200,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
}),
).toEqual({
success: false,
@ -222,7 +222,7 @@ describe('InviteToSharedSubscription', () => {
inviteeIdentifier: 'invitee@test.te',
inviterUuid: '1-2-3',
inviterEmail: 'inviter@test.te',
inviterRoles: [RoleName.ProUser],
inviterRoles: [RoleName.NAMES.ProUser],
}),
).toEqual({
success: true,

View file

@ -1,6 +1,5 @@
import { RoleName } from '@standardnotes/common'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { EmailLevel } from '@standardnotes/domain-core'
import { EmailLevel, RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
@ -32,7 +31,7 @@ export class InviteToSharedSubscription implements UseCaseInterface {
) {}
async execute(dto: InviteToSharedSubscriptionDTO): Promise<InviteToSharedSubscriptionResult> {
if (!dto.inviterRoles.includes(RoleName.ProUser)) {
if (!dto.inviterRoles.includes(RoleName.NAMES.ProUser)) {
return {
success: false,
}

View file

@ -1,8 +1,8 @@
import { RoleName, Uuid } from '@standardnotes/common'
import { Uuid } from '@standardnotes/common'
export type InviteToSharedSubscriptionDTO = {
inviterEmail: string
inviterUuid: Uuid
inviterRoles: RoleName[]
inviterRoles: string[]
inviteeIdentifier: string
}

View file

@ -1,5 +1,5 @@
import * as bcrypt from 'bcryptjs'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { ApiVersion } from '@standardnotes/api'
import { v4 as uuidv4 } from 'uuid'
@ -63,7 +63,7 @@ export class Register implements UseCaseInterface {
user.encryptedServerKey = await this.crypter.generateEncryptedUserServerKey()
user.serverEncryptionVersion = User.DEFAULT_ENCRYPTION_VERSION
const defaultRole = await this.roleRepository.findOneByName(RoleName.CoreUser)
const defaultRole = await this.roleRepository.findOneByName(RoleName.NAMES.CoreUser)
if (defaultRole) {
user.roles = Promise.resolve([defaultRole])
}

View file

@ -1,4 +1,3 @@
import { RoleName } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
@ -18,7 +17,7 @@ export class WebSocketsClientService implements ClientServiceInterface {
const event = this.domainEventFactory.createUserRolesChangedEvent(
user.uuid,
user.email,
(await user.roles).map((role) => role.name) as RoleName[],
(await user.roles).map((role) => role.name),
)
await this.domainEventPublisher.publish(

View file

@ -1,4 +0,0 @@
/* istanbul ignore file */
import { RoleName } from './RoleName'
export const PaidRoles = [RoleName.CoreUser, RoleName.PlusUser, RoleName.ProUser]

View file

@ -1,7 +0,0 @@
/* istanbul ignore file */
export enum RoleName {
CoreUser = 'CORE_USER',
PlusUser = 'PLUS_USER',
ProUser = 'PRO_USER',
FilesBetaUser = 'FILES_BETA_USER',
}

View file

@ -17,8 +17,6 @@ export * from './KeyParams/KeyParamsContent004'
export * from './KeyParams/KeyParamsOrigination'
export * from './Payment/PaymentType'
export * from './Protocol/ProtocolVersion'
export * from './Role/PaidRoles'
export * from './Role/RoleName'
export * from './Subscription/SubscriptionBillingFrequency'
export * from './Subscription/SubscriptionName'
export * from './Type/Either'

View file

@ -1,8 +1,6 @@
import { RoleName } from '@standardnotes/common'
export interface UserRolesChangedEventPayload {
userUuid: string
email: string
currentRoles: RoleName[]
currentRoles: string[]
timestamp: number
}

View file

@ -1,6 +1,6 @@
import { Uuid, RoleName } from '@standardnotes/common'
import { Uuid } from '@standardnotes/common'
export type Role = {
uuid: Uuid
name: RoleName
name: string
}

View file

@ -5,7 +5,7 @@ import * as winston from 'winston'
import { AuthMiddleware } from './AuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { sign } from 'jsonwebtoken'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
describe('AuthMiddleware', () => {
let logger: winston.Logger
@ -43,11 +43,11 @@ describe('AuthMiddleware', () => {
roles: [
{
uuid: '1-2-3',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
{
uuid: '2-3-4',
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
},
],
permissions: [],
@ -77,7 +77,7 @@ describe('AuthMiddleware', () => {
roles: [
{
uuid: '1-2-3',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
],
permissions: [],
@ -106,11 +106,11 @@ describe('AuthMiddleware', () => {
roles: [
{
uuid: '1-2-3',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
{
uuid: '2-3-4',
name: RoleName.ProUser,
name: RoleName.NAMES.ProUser,
},
],
permissions: [],

View file

@ -4,8 +4,9 @@ import { BaseMiddleware } from 'inversify-express-utils'
import { verify } from 'jsonwebtoken'
import { CrossServiceTokenData } from '@standardnotes/security'
import * as winston from 'winston'
import { RoleName } from '@standardnotes/domain-core'
import TYPES from '../Bootstrap/Types'
import { RoleName } from '@standardnotes/common'
@injectable()
export class AuthMiddleware extends BaseMiddleware {
@ -29,7 +30,7 @@ export class AuthMiddleware extends BaseMiddleware {
response.locals.user = decodedToken.user
response.locals.roleNames = decodedToken.roles.map((role) => role.name)
response.locals.freeUser =
response.locals.roleNames.length === 1 && response.locals.roleNames[0] === RoleName.CoreUser
response.locals.roleNames.length === 1 && response.locals.roleNames[0] === RoleName.NAMES.CoreUser
response.locals.session = decodedToken.session
response.locals.readOnlyAccess = decodedToken.session?.readonly_access ?? false

View file

@ -1,6 +1,6 @@
import 'reflect-metadata'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { Item } from '../Item/Item'
@ -99,7 +99,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser],
userRoles: [RoleName.NAMES.CoreUser],
userUuid: '1-2-3',
revisionUuid: '3-4-5',
}),
@ -112,7 +112,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser],
userRoles: [RoleName.NAMES.CoreUser],
userUuid: '3-4-5',
revisionUuid: '3-4-5',
}),
@ -125,7 +125,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser],
userRoles: [RoleName.NAMES.CoreUser],
userUuid: '1-2-3',
revisionUuid: '3-4-5',
}),
@ -138,7 +138,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser],
userRoles: [RoleName.NAMES.CoreUser],
userUuid: '1-2-3',
revisionUuid: '3-4-5',
}),
@ -151,7 +151,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser],
userRoles: [RoleName.NAMES.CoreUser],
userUuid: '1-2-3',
revisionUuid: '3-4-5',
}),
@ -164,7 +164,7 @@ describe('RevisionService', () => {
expect(
await createService().getRevision({
itemUuid: '1-2-3',
userRoles: [RoleName.CoreUser, RoleName.PlusUser],
userRoles: [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser],
userUuid: '1-2-3',
revisionUuid: '3-4-5',
}),

View file

@ -1,5 +1,5 @@
import { inject, injectable } from 'inversify'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import TYPES from '../../Bootstrap/Types'
@ -39,7 +39,7 @@ export class RevisionService implements RevisionServiceInterface {
async getRevision(dto: {
userUuid: string
userRoles: RoleName[]
userRoles: string[]
itemUuid: string
revisionUuid: string
}): Promise<Revision | null> {
@ -57,28 +57,31 @@ export class RevisionService implements RevisionServiceInterface {
return revision
}
calculateRequiredRoleBasedOnRevisionDate(createdAt: Date): RoleName {
calculateRequiredRoleBasedOnRevisionDate(createdAt: Date): string {
const revisionCreatedNDaysAgo = this.timer.dateWasNDaysAgo(createdAt)
if (revisionCreatedNDaysAgo > 30 && revisionCreatedNDaysAgo < 365) {
return RoleName.PlusUser
return RoleName.NAMES.PlusUser
}
if (revisionCreatedNDaysAgo > 365) {
return RoleName.ProUser
return RoleName.NAMES.ProUser
}
return RoleName.CoreUser
return RoleName.NAMES.CoreUser
}
private userHasEnoughPermissionsToSeeRevision(userRoles: RoleName[], revisionCreatedAt: Date): boolean {
private userHasEnoughPermissionsToSeeRevision(userRoles: string[], revisionCreatedAt: Date): boolean {
const roleRequired = this.calculateRequiredRoleBasedOnRevisionDate(revisionCreatedAt)
switch (roleRequired) {
case RoleName.PlusUser:
return userRoles.filter((userRole) => [RoleName.PlusUser, RoleName.ProUser].includes(userRole)).length > 0
case RoleName.ProUser:
return userRoles.includes(RoleName.ProUser)
case RoleName.NAMES.PlusUser:
return (
userRoles.filter((userRole) => [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser].includes(userRole)).length >
0
)
case RoleName.NAMES.ProUser:
return userRoles.includes(RoleName.NAMES.ProUser)
default:
return true
}

View file

@ -1,4 +1,3 @@
import { RoleName } from '@standardnotes/common'
import { Revision } from './Revision'
import { RevisionMetadata } from './RevisionMetadata'
@ -6,10 +5,10 @@ export interface RevisionServiceInterface {
getRevisionsMetadata(userUuid: string, itemUuid: string): Promise<RevisionMetadata[]>
getRevision(dto: {
userUuid: string
userRoles: RoleName[]
userRoles: string[]
itemUuid: string
revisionUuid: string
}): Promise<Revision | null>
removeRevision(dto: { userUuid: string; itemUuid: string; revisionUuid: string }): Promise<boolean>
calculateRequiredRoleBasedOnRevisionDate(createdAt: Date): RoleName
calculateRequiredRoleBasedOnRevisionDate(createdAt: Date): string
}

View file

@ -1,4 +1,4 @@
import { ContentType, RoleName } from '@standardnotes/common'
import { ContentType } from '@standardnotes/common'
export type RevisionProjection = {
uuid: string
@ -9,7 +9,7 @@ export type RevisionProjection = {
enc_item_key: string | null
auth_hash: string | null
creation_date: string
required_role: RoleName
required_role: string
created_at: string
updated_at: string
}

View file

@ -1,4 +1,5 @@
import { ContentType, RoleName } from '@standardnotes/common'
import { ContentType } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { Item } from '../Domain/Item/Item'
@ -26,7 +27,7 @@ describe('RevisionProjector', () => {
timer.formatDate = jest.fn().mockReturnValue('2020-11-26')
revisionService = {} as jest.Mocked<RevisionServiceInterface>
revisionService.calculateRequiredRoleBasedOnRevisionDate = jest.fn().mockReturnValue(RoleName.CoreUser)
revisionService.calculateRequiredRoleBasedOnRevisionDate = jest.fn().mockReturnValue(RoleName.NAMES.CoreUser)
revision.creationDate = new Date(1)
revision.createdAt = new Date(1)

View file

@ -1,9 +1,9 @@
import { ContentType, RoleName } from '@standardnotes/common'
import { ContentType } from '@standardnotes/common'
export type SimpleRevisionProjection = {
uuid: string
content_type: ContentType | null
required_role: RoleName
required_role: string
created_at: string
updated_at: string
}

View file

@ -26,6 +26,7 @@
"@sentry/node": "^7.28.1",
"@standardnotes/api": "^1.19.0",
"@standardnotes/common": "workspace:^",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:^",
"@standardnotes/domain-events-infra": "workspace:^",
"@standardnotes/security": "workspace:^",

View file

@ -4,7 +4,7 @@ import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { Logger } from 'winston'
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
describe('ApiGatewayAuthMiddleware', () => {
let tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>
@ -28,7 +28,7 @@ describe('ApiGatewayAuthMiddleware', () => {
roles: [
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
],
})
@ -56,7 +56,7 @@ describe('ApiGatewayAuthMiddleware', () => {
expect(response.locals.roles).toEqual([
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
])

View file

@ -4,7 +4,7 @@ import { ApiGatewayAuthMiddleware } from './ApiGatewayAuthMiddleware'
import { NextFunction, Request, Response } from 'express'
import { Logger } from 'winston'
import { CrossServiceTokenData, TokenDecoderInterface } from '@standardnotes/security'
import { RoleName } from '@standardnotes/common'
import { RoleName } from '@standardnotes/domain-core'
describe('ApiGatewayAuthMiddleware', () => {
let tokenDecoder: TokenDecoderInterface<CrossServiceTokenData>
@ -28,7 +28,7 @@ describe('ApiGatewayAuthMiddleware', () => {
roles: [
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
],
})
@ -56,7 +56,7 @@ describe('ApiGatewayAuthMiddleware', () => {
expect(response.locals.roles).toEqual([
{
uuid: 'a-b-c',
name: RoleName.CoreUser,
name: RoleName.NAMES.CoreUser,
},
])

View file

@ -1920,7 +1920,7 @@ __metadata:
dependencies:
"@newrelic/winston-enricher": "npm:^4.0.0"
"@sentry/node": "npm:^7.28.1"
"@standardnotes/common": "workspace:^"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/security": "workspace:*"
@ -2603,6 +2603,7 @@ __metadata:
"@sentry/node": "npm:^7.28.1"
"@standardnotes/api": "npm:^1.19.0"
"@standardnotes/common": "workspace:^"
"@standardnotes/domain-core": "workspace:^"
"@standardnotes/domain-events": "workspace:^"
"@standardnotes/domain-events-infra": "workspace:^"
"@standardnotes/security": "workspace:^"