Compare commits

..

19 Commits

Author SHA1 Message Date
standardci 7f4776b52b chore(release): publish new version
- @standardnotes/analytics@2.19.11
 - @standardnotes/api-gateway@1.46.6
 - @standardnotes/auth-server@1.84.5
 - @standardnotes/common@1.46.4
 - @standardnotes/domain-core@1.11.2
 - @standardnotes/domain-events-infra@1.9.66
 - @standardnotes/domain-events@2.106.1
 - @standardnotes/event-store@1.6.65
 - @standardnotes/files-server@1.9.11
 - @standardnotes/predicates@1.6.5
 - @standardnotes/revisions-server@1.10.19
 - @standardnotes/scheduler-server@1.16.15
 - @standardnotes/security@1.7.6
 - @standardnotes/settings@1.19.1
 - @standardnotes/sncrypto-node@1.13.1
 - @standardnotes/syncing-server@1.29.7
 - @standardnotes/time@1.14.1
 - @standardnotes/websockets-server@1.5.11
 - @standardnotes/workspace-server@1.19.14
2023-01-20 10:59:12 +00:00
Karol Sójko d20f03127a chore(deps): upgrade eslint tools 2023-01-20 10:16:04 +01:00
Karol Sójko 4b6c7774e0 chore: bring back e2e tests 2023-01-20 09:54:30 +01:00
standardci d02bca8879 chore(release): publish new version
- @standardnotes/auth-server@1.84.4
2023-01-20 00:06:06 +00:00
moughxyz 5e654ccf94 temp: disable e2e tests 2023-01-19 18:03:54 -06:00
standardci 7d3e5c22fb chore(release): publish new version
- @standardnotes/auth-server@1.84.2
2023-01-19 23:29:14 +00:00
moughxyz 23eb61ee5f refactor: offlineRoles => roles 2023-01-19 17:27:20 -06:00
standardci 2cded4b2d1 chore(release): publish new version
- @standardnotes/auth-server@1.84.1
 - @standardnotes/syncing-server@1.29.6
2023-01-19 23:25:55 +00:00
moughxyz ba7662fc1e fix: strings for role names 2023-01-19 17:23:58 -06:00
standardci 832a48ac76 chore(release): publish new version
- @standardnotes/analytics@2.19.10
 - @standardnotes/api-gateway@1.46.5
 - @standardnotes/auth-server@1.84.0
 - @standardnotes/domain-events-infra@1.9.65
 - @standardnotes/domain-events@2.106.0
 - @standardnotes/event-store@1.6.64
 - @standardnotes/files-server@1.9.10
 - @standardnotes/revisions-server@1.10.18
 - @standardnotes/scheduler-server@1.16.14
 - @standardnotes/syncing-server@1.29.5
 - @standardnotes/websockets-server@1.5.10
 - @standardnotes/workspace-server@1.19.13
2023-01-19 22:31:28 +00:00
Mo 2db0c125fe feat: offline roles (#419) 2023-01-19 16:29:36 -06:00
standardci 20d9624bc6 chore(release): publish new version
- @standardnotes/auth-server@1.83.1
2023-01-19 19:40:49 +00:00
moughxyz f20ee68f50 Revert "feat: include roles in offline features request (#418)"
This reverts commit 2e7fdd93dd.
2023-01-19 13:38:46 -06:00
standardci cbf45ce3eb chore(release): publish new version
- @standardnotes/auth-server@1.83.0
2023-01-19 19:18:16 +00:00
Mo 2e7fdd93dd feat: include roles in offline features request (#418) 2023-01-19 13:16:16 -06:00
standardci 8ce38f82b5 chore(release): publish new version
- @standardnotes/analytics@2.19.9
 - @standardnotes/api-gateway@1.46.4
 - @standardnotes/auth-server@1.82.6
 - @standardnotes/domain-events-infra@1.9.64
 - @standardnotes/domain-events@2.105.5
 - @standardnotes/event-store@1.6.63
 - @standardnotes/files-server@1.9.9
 - @standardnotes/revisions-server@1.10.17
 - @standardnotes/scheduler-server@1.16.13
 - @standardnotes/syncing-server@1.29.4
 - @standardnotes/websockets-server@1.5.9
 - @standardnotes/workspace-server@1.19.12
2023-01-19 16:19:54 +00:00
Aman Harwara ec5429eeec fix: expected value for unit test (#417) 2023-01-19 21:47:32 +05:30
standardci 4b17c4045d chore(release): publish new version
- @standardnotes/analytics@2.19.8
 - @standardnotes/api-gateway@1.46.3
 - @standardnotes/auth-server@1.82.5
 - @standardnotes/common@1.46.3
 - @standardnotes/domain-events-infra@1.9.63
 - @standardnotes/domain-events@2.105.4
 - @standardnotes/event-store@1.6.62
 - @standardnotes/files-server@1.9.8
 - @standardnotes/predicates@1.6.4
 - @standardnotes/revisions-server@1.10.16
 - @standardnotes/scheduler-server@1.16.12
 - @standardnotes/security@1.7.5
 - @standardnotes/syncing-server@1.29.3
 - @standardnotes/websockets-server@1.5.8
 - @standardnotes/workspace-server@1.19.11
2023-01-19 14:13:50 +00:00
Karol Sójko aaf42e4693 refactor: remove Uuid from @standardnotes/common in favour of @standardnotes/domain-core definition 2023-01-19 15:11:47 +01:00
192 changed files with 995 additions and 1190 deletions
Generated
+264 -441
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -51,7 +51,7 @@
"@types/newrelic": "^9.4.0",
"@types/node": "^18.11.9",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.17.0",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.5.0",
"ini": "^3.0.0",
"npm-check-updates": "^16.0.1",
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.19.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.10...@standardnotes/analytics@2.19.11) (2023-01-20)
**Note:** Version bump only for package @standardnotes/analytics
## [2.19.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.9...@standardnotes/analytics@2.19.10) (2023-01-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.19.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.8...@standardnotes/analytics@2.19.9) (2023-01-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.19.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.7...@standardnotes/analytics@2.19.8) (2023-01-19)
**Note:** Version bump only for package @standardnotes/analytics
## [2.19.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.6...@standardnotes/analytics@2.19.7) (2023-01-19)
**Note:** Version bump only for package @standardnotes/analytics
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.19.7",
"version": "2.19.11",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -30,8 +30,8 @@
"@types/mixpanel": "^2.14.4",
"@types/newrelic": "^9.4.0",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint": "^8.14.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"eslint": "^8.32.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.1.2",
"ts-jest": "^29.0.3",
@@ -1,9 +1,8 @@
import { Uuid } from '@standardnotes/common'
import { AnalyticsEntity } from './AnalyticsEntity'
export interface AnalyticsEntityRepositoryInterface {
save(analyticsEntity: AnalyticsEntity): Promise<AnalyticsEntity>
remove(analyticsEntity: AnalyticsEntity): Promise<void>
findOneByUserUuid(userUuid: Uuid): Promise<AnalyticsEntity | null>
findOneByUserUuid(userUuid: string): Promise<AnalyticsEntity | null>
findOneByUserEmail(email: string): Promise<AnalyticsEntity | null>
}
@@ -1,8 +1,8 @@
import { Either, Uuid } from '@standardnotes/common'
import { Either } from '@standardnotes/common'
export type GetUserAnalyticsIdDTO = Either<
{
userUuid: Uuid
userUuid: string
},
{
userEmail: string
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm'
@@ -20,7 +19,7 @@ export class MySQLAnalyticsEntityRepository implements AnalyticsEntityRepository
.getOne()
}
async findOneByUserUuid(userUuid: Uuid): Promise<AnalyticsEntity | null> {
async findOneByUserUuid(userUuid: string): Promise<AnalyticsEntity | null> {
return this.ormRepository
.createQueryBuilder('analytics_entity')
.where('analytics_entity.user_uuid = :userUuid', { userUuid })
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.46.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.46.5...@standardnotes/api-gateway@1.46.6) (2023-01-20)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.46.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.46.4...@standardnotes/api-gateway@1.46.5) (2023-01-19)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.46.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.46.3...@standardnotes/api-gateway@1.46.4) (2023-01-19)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.46.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.46.2...@standardnotes/api-gateway@1.46.3) (2023-01-19)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.46.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.46.1...@standardnotes/api-gateway@1.46.2) (2023-01-19)
**Note:** Version bump only for package @standardnotes/api-gateway
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.46.2",
"version": "1.46.6",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -51,8 +51,8 @@
"@types/jsonwebtoken": "^9.0.1",
"@types/newrelic": "^9.4.0",
"@types/prettyjson": "^0.0.30",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"eslint": "^8.14.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"eslint": "^8.32.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^29.1.2",
"nodemon": "^2.0.19",
+46
View File
@@ -3,6 +3,52 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.84.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.4...@standardnotes/auth-server@1.84.5) (2023-01-20)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.84.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.2...@standardnotes/auth-server@1.84.4) (2023-01-20)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.84.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.1...@standardnotes/auth-server@1.84.2) (2023-01-19)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.84.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.84.0...@standardnotes/auth-server@1.84.1) (2023-01-19)
### Bug Fixes
* strings for role names ([ba7662f](https://github.com/standardnotes/server/commit/ba7662fc1ea24548ab4ea287c5f34d6f27c6c923))
# [1.84.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.83.1...@standardnotes/auth-server@1.84.0) (2023-01-19)
### Features
* offline roles ([#419](https://github.com/standardnotes/server/issues/419)) ([2db0c12](https://github.com/standardnotes/server/commit/2db0c125fe5872c5898103c2388881ab416b5a99))
## [1.83.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.83.0...@standardnotes/auth-server@1.83.1) (2023-01-19)
### Reverts
* Revert "feat: include roles in offline features request (#418)" ([f20ee68](https://github.com/standardnotes/server/commit/f20ee68f504449b6ff37748c4d7f83c08bb4039d)), closes [#418](https://github.com/standardnotes/server/issues/418)
# [1.83.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.82.6...@standardnotes/auth-server@1.83.0) (2023-01-19)
### Features
* include roles in offline features request ([#418](https://github.com/standardnotes/server/issues/418)) ([2e7fdd9](https://github.com/standardnotes/server/commit/2e7fdd93dd3b07e0a9f2e72521251af1d15660d4))
## [1.82.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.82.5...@standardnotes/auth-server@1.82.6) (2023-01-19)
### Bug Fixes
* expected value for unit test ([#417](https://github.com/standardnotes/server/issues/417)) ([ec5429e](https://github.com/standardnotes/server/commit/ec5429eeec8ea6422ed6e0e798e0f16aa9f78c95))
## [1.82.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.82.4...@standardnotes/auth-server@1.82.5) (2023-01-19)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.82.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.82.3...@standardnotes/auth-server@1.82.4) (2023-01-19)
**Note:** Version bump only for package @standardnotes/auth-server
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.82.4",
"version": "1.84.5",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -42,7 +42,7 @@
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/features": "^1.58.0",
"@standardnotes/features": "^1.58.1",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.6.39",
"@standardnotes/security": "workspace:*",
@@ -81,8 +81,8 @@
"@types/prettyjson": "^0.0.30",
"@types/ua-parser-js": "^0.7.36",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"eslint": "^8.14.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"eslint": "^8.32.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^29.1.2",
"nodemon": "^2.0.19",
+1 -9
View File
@@ -121,14 +121,7 @@ import { RedisOfflineSubscriptionTokenRepository } from '../Infra/Redis/RedisOff
import { CreateOfflineSubscriptionToken } from '../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken'
import { AuthenticateOfflineSubscriptionToken } from '../Domain/UseCase/AuthenticateOfflineSubscriptionToken/AuthenticateOfflineSubscriptionToken'
import { SubscriptionCancelledEventHandler } from '../Domain/Handler/SubscriptionCancelledEventHandler'
import {
ContentDecoder,
ContentDecoderInterface,
ProtocolVersion,
Uuid,
UuidValidator,
ValidatorInterface,
} from '@standardnotes/common'
import { ContentDecoder, ContentDecoderInterface, ProtocolVersion } from '@standardnotes/common'
import { GetUserOfflineSubscription } from '../Domain/UseCase/GetUserOfflineSubscription/GetUserOfflineSubscription'
import { ApiGatewayOfflineAuthMiddleware } from '../Controller/ApiGatewayOfflineAuthMiddleware'
import { UserEmailChangedEventHandler } from '../Domain/Handler/UserEmailChangedEventHandler'
@@ -532,7 +525,6 @@ export class ContainerConfigLoader {
.bind<SelectorInterface<boolean>>(TYPES.BooleanSelector)
.toConstantValue(new DeterministicSelector<boolean>())
container.bind<UserSubscriptionServiceInterface>(TYPES.UserSubscriptionService).to(UserSubscriptionService)
container.bind<ValidatorInterface<Uuid>>(TYPES.UuidValidator).toConstantValue(new UuidValidator())
if (env.get('SNS_TOPIC_ARN', true)) {
container
-1
View File
@@ -207,7 +207,6 @@ const TYPES = {
ProtocolVersionSelector: Symbol.for('ProtocolVersionSelector'),
BooleanSelector: Symbol.for('BooleanSelector'),
UserSubscriptionService: Symbol.for('UserSubscriptionService'),
UuidValidator: Symbol.for('UuidValidator'),
}
export default TYPES
@@ -4,27 +4,22 @@ import { Request, Response } from 'express'
import { results } from 'inversify-express-utils'
import { ValetTokenController } from './ValetTokenController'
import { CreateValetToken } from '../Domain/UseCase/CreateValetToken/CreateValetToken'
import { Uuid, ValidatorInterface } from '@standardnotes/common'
describe('ValetTokenController', () => {
let createValetToken: CreateValetToken
let uuidValidator: ValidatorInterface<Uuid>
let request: Request
let response: Response
const createController = () => new ValetTokenController(createValetToken, uuidValidator)
const createController = () => new ValetTokenController(createValetToken)
beforeEach(() => {
createValetToken = {} as jest.Mocked<CreateValetToken>
createValetToken.execute = jest.fn().mockReturnValue({ success: true, valetToken: 'foobar' })
uuidValidator = {} as jest.Mocked<ValidatorInterface<Uuid>>
uuidValidator.validate = jest.fn().mockReturnValue(true)
request = {
body: {
operation: 'write',
resources: ['1-2-3/2-3-4'],
resources: [{ remoteIdentifier: '00000000-0000-0000-0000-000000000000' }],
},
} as jest.Mocked<Request>
@@ -42,13 +37,13 @@ describe('ValetTokenController', () => {
expect(createValetToken.execute).toHaveBeenCalledWith({
operation: 'write',
userUuid: '1-2-3',
resources: ['1-2-3/2-3-4'],
resources: [{ remoteIdentifier: '00000000-0000-0000-0000-000000000000' }],
})
expect(await result.content.readAsStringAsync()).toEqual('{"success":true,"valetToken":"foobar"}')
})
it('should not create a valet token if the remote resource identifier is not a valid uuid', async () => {
uuidValidator.validate = jest.fn().mockReturnValue(false)
request.body.resources = ['00000000-0000-0000-0000-000000000000', 'invalid-uuid']
const httpResponse = <results.JsonResult>await createController().create(request, response)
const result = await httpResponse.executeAsync()
@@ -68,7 +63,7 @@ describe('ValetTokenController', () => {
expect(createValetToken.execute).toHaveBeenCalledWith({
operation: 'read',
userUuid: '1-2-3',
resources: ['1-2-3/2-3-4'],
resources: [{ remoteIdentifier: '00000000-0000-0000-0000-000000000000' }],
})
expect(await result.content.readAsStringAsync()).toEqual('{"success":true,"valetToken":"foobar"}')
})
@@ -106,7 +101,7 @@ describe('ValetTokenController', () => {
expect(createValetToken.execute).toHaveBeenCalledWith({
operation: 'write',
userUuid: '1-2-3',
resources: ['1-2-3/2-3-4'],
resources: [{ remoteIdentifier: '00000000-0000-0000-0000-000000000000' }],
})
expect(await result.content.readAsStringAsync()).toEqual('{"success":false}')
@@ -11,15 +11,13 @@ import { CreateValetTokenPayload } from '@standardnotes/responses'
import TYPES from '../Bootstrap/Types'
import { CreateValetToken } from '../Domain/UseCase/CreateValetToken/CreateValetToken'
import { ErrorTag, Uuid, ValidatorInterface } from '@standardnotes/common'
import { ErrorTag } from '@standardnotes/common'
import { ValetTokenOperation } from '@standardnotes/security'
import { Uuid } from '@standardnotes/domain-core'
@controller('/valet-tokens', TYPES.ApiGatewayAuthMiddleware)
export class ValetTokenController extends BaseHttpController {
constructor(
@inject(TYPES.CreateValetToken) private createValetKey: CreateValetToken,
@inject(TYPES.UuidValidator) private uuidValitor: ValidatorInterface<Uuid>,
) {
constructor(@inject(TYPES.CreateValetToken) private createValetKey: CreateValetToken) {
super()
}
@@ -40,7 +38,8 @@ export class ValetTokenController extends BaseHttpController {
}
for (const resource of payload.resources) {
if (!this.uuidValitor.validate(resource.remoteIdentifier)) {
const resourceUuidOrError = Uuid.create(resource.remoteIdentifier)
if (resourceUuidOrError.isFailed()) {
return this.json(
{
error: {
@@ -1,8 +1,8 @@
import { ProtocolVersion, Uuid } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
export interface AuthResponse {
user: {
uuid: Uuid
uuid: string
email: string
protocolVersion: ProtocolVersion
}
@@ -1,5 +1,5 @@
import { SessionTokenData, TokenEncoderInterface } from '@standardnotes/security'
import { ProtocolVersion, Uuid } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import * as crypto from 'crypto'
import { inject, injectable } from 'inversify'
@@ -40,7 +40,7 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface
return {
user: this.userProjector.projectSimple(dto.user) as {
uuid: Uuid
uuid: string
email: string
protocolVersion: ProtocolVersion
},
@@ -3,7 +3,7 @@ import {
SessionTokenData,
TokenEncoderInterface,
} from '@standardnotes/security'
import { ProtocolVersion, Uuid } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { SessionBody } from '@standardnotes/responses'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -49,7 +49,7 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 {
session: sessionPayload,
key_params: this.keyParamsFactory.create(dto.user, true),
user: this.userProjector.projectSimple(dto.user) as {
uuid: Uuid
uuid: string
email: string
protocolVersion: ProtocolVersion
},
@@ -1,6 +1,6 @@
/* istanbul ignore file */
import { JSONString, ProtocolVersion, Uuid } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import {
AccountDeletionRequestedEvent,
UserEmailChangedEvent,
@@ -105,7 +105,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
}
createWebSocketMessageRequestedEvent(dto: { userUuid: Uuid; message: JSONString }): WebSocketMessageRequestedEvent {
createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: string }): WebSocketMessageRequestedEvent {
return {
type: 'WEB_SOCKET_MESSAGE_REQUESTED',
createdAt: this.timer.getUTCDate(),
@@ -142,7 +142,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
createPredicateVerifiedEvent(dto: {
userUuid: Uuid
userUuid: string
predicate: Predicate
predicateVerificationResult: PredicateVerificationResult
}): PredicateVerifiedEvent {
@@ -164,10 +164,10 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
createSharedSubscriptionInvitationCanceledEvent(dto: {
inviterEmail: string
inviterSubscriptionId: number
inviterSubscriptionUuid: Uuid
inviterSubscriptionUuid: string
inviteeIdentifier: string
inviteeIdentifierType: InviteeIdentifierType
sharedSubscriptionInvitationUuid: Uuid
sharedSubscriptionInvitationUuid: string
}): SharedSubscriptionInvitationCanceledEvent {
return {
type: 'SHARED_SUBSCRIPTION_INVITATION_CANCELED',
@@ -291,9 +291,9 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}
createAccountDeletionRequestedEvent(dto: {
userUuid: Uuid
userUuid: string
userCreatedAtTimestamp: number
regularSubscriptionUuid: Uuid | undefined
regularSubscriptionUuid: string | undefined
}): AccountDeletionRequestedEvent {
return {
type: 'ACCOUNT_DELETION_REQUESTED',
@@ -1,4 +1,4 @@
import { Uuid, ProtocolVersion, JSONString } from '@standardnotes/common'
import { ProtocolVersion, JSONString } from '@standardnotes/common'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import {
AccountDeletionRequestedEvent,
@@ -23,7 +23,7 @@ import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierTy
export interface DomainEventFactoryInterface {
createUserContentSizeRecalculationRequestedEvent(userUuid: string): UserContentSizeRecalculationRequestedEvent
createWebSocketMessageRequestedEvent(dto: { userUuid: Uuid; message: JSONString }): WebSocketMessageRequestedEvent
createWebSocketMessageRequestedEvent(dto: { userUuid: string; message: JSONString }): WebSocketMessageRequestedEvent
createEmailRequestedEvent(dto: {
userEmail: string
messageIdentifier: string
@@ -50,14 +50,14 @@ export interface DomainEventFactoryInterface {
userHasEmailsMuted: boolean,
): CloudBackupRequestedEvent
createAccountDeletionRequestedEvent(dto: {
userUuid: Uuid
userUuid: string
userCreatedAtTimestamp: number
regularSubscriptionUuid: Uuid | undefined
regularSubscriptionUuid: string | undefined
}): AccountDeletionRequestedEvent
createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: string[]): UserRolesChangedEvent
createUserEmailChangedEvent(userUuid: string, fromEmail: string, toEmail: string): UserEmailChangedEvent
createUserDisabledSessionUserAgentLoggingEvent(dto: {
userUuid: Uuid
userUuid: string
email: string
}): UserDisabledSessionUserAgentLoggingEvent
createSharedSubscriptionInvitationCreatedEvent(dto: {
@@ -70,13 +70,13 @@ export interface DomainEventFactoryInterface {
createSharedSubscriptionInvitationCanceledEvent(dto: {
inviterEmail: string
inviterSubscriptionId: number
inviterSubscriptionUuid: Uuid
inviterSubscriptionUuid: string
inviteeIdentifier: string
inviteeIdentifierType: InviteeIdentifierType
sharedSubscriptionInvitationUuid: Uuid
sharedSubscriptionInvitationUuid: string
}): SharedSubscriptionInvitationCanceledEvent
createPredicateVerifiedEvent(dto: {
userUuid: Uuid
userUuid: string
predicate: Predicate
predicateVerificationResult: PredicateVerificationResult
}): PredicateVerifiedEvent
@@ -8,6 +8,27 @@ import { RoleToSubscriptionMapInterface } from '../Role/RoleToSubscriptionMapInt
import { User } from '../User/User'
import { UserSubscription } from '../Subscription/UserSubscription'
jest.mock('@standardnotes/features', () => {
const original = jest.requireActual('@standardnotes/features')
return {
...original,
GetFeatures: jest.fn().mockImplementation(() => [
{
identifier: 'org.standardnotes.theme-autobiography',
permission_name: original.PermissionName.AutobiographyTheme,
expires_at: 555,
},
{
identifier: 'org.standardnotes.bold-editor',
permission_name: original.PermissionName.BoldEditor,
expires_at: 777,
},
]),
}
})
const { GetFeatures } = jest.requireMock('@standardnotes/features')
import { FeatureService } from './FeatureService'
import { Permission, PermissionName } from '@standardnotes/features'
import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
@@ -160,9 +181,9 @@ describe('FeatureService', () => {
describe('offline subscribers', () => {
it('should return user features with `expires_at` field', async () => {
const features = await createService().getFeaturesForOfflineUser('test@test.com')
const featuresResponse = await createService().getFeaturesForOfflineUser('test@test.com')
expect(features).toEqual(
expect(featuresResponse.features).toEqual(
expect.arrayContaining([
expect.objectContaining({
identifier: 'org.standardnotes.theme-autobiography',
@@ -175,7 +196,7 @@ describe('FeatureService', () => {
it('should not return user features if a subscription could not be found', async () => {
offlineUserSubscriptionRepository.findByEmail = jest.fn().mockReturnValue([])
expect(await createService().getFeaturesForOfflineUser('test@test.com')).toEqual([])
expect(await createService().getFeaturesForOfflineUser('test@test.com')).toEqual({ features: [], roles: [] })
})
})
@@ -303,6 +324,24 @@ describe('FeatureService', () => {
name: PermissionName.FilesBeta,
} as jest.Mocked<Permission>
GetFeatures.mockImplementation(() => [
{
identifier: 'org.standardnotes.theme-autobiography',
permission_name: PermissionName.AutobiographyTheme,
expires_at: 555,
},
{
identifier: 'org.standardnotes.bold-editor',
permission_name: PermissionName.BoldEditor,
expires_at: 777,
},
{
permission_name: PermissionName.FilesBeta,
expires_at: undefined,
no_expire: true,
},
])
const nonSubscriptionRole = {
name: RoleName.NAMES.FilesBetaUser,
uuid: 'role-files-beta',
@@ -333,7 +372,6 @@ describe('FeatureService', () => {
expires_at: 777,
}),
expect.objectContaining({
identifier: 'org.standardnotes.files-beta',
expires_at: undefined,
no_expire: true,
}),
@@ -21,7 +21,7 @@ export class FeatureService implements FeatureServiceInterface {
@inject(TYPES.Timer) private timer: TimerInterface,
) {}
async getFeaturesForOfflineUser(email: string): Promise<FeatureDescription[]> {
async getFeaturesForOfflineUser(email: string): Promise<{ features: FeatureDescription[]; roles: string[] }> {
const userSubscriptions = await this.offlineUserSubscriptionRepository.findByEmail(
email,
this.timer.getTimestampInMicroseconds(),
@@ -34,7 +34,11 @@ export class FeatureService implements FeatureServiceInterface {
}
}
return this.getFeaturesForSubscriptions(userSubscriptions, [...userRolesMap.values()])
const roles = [...userRolesMap.values()]
return {
features: await this.getFeaturesForSubscriptions(userSubscriptions, roles),
roles: roles.map((role) => role.name),
}
}
async getFeaturesForUser(user: User): Promise<Array<FeatureDescription>> {
@@ -4,5 +4,5 @@ import { User } from '../User/User'
export interface FeatureServiceInterface {
getFeaturesForUser(user: User): Promise<Array<FeatureDescription>>
getFeaturesForOfflineUser(email: string): Promise<FeatureDescription[]>
getFeaturesForOfflineUser(email: string): Promise<{ features: FeatureDescription[]; roles: string[] }>
}
@@ -1,4 +1,3 @@
import { SubscriptionName } from '@standardnotes/common'
import { DomainEventHandlerInterface, SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -38,10 +37,7 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
await this.removeRoleFromSubscriptionUsers(event.payload.subscriptionId, event.payload.subscriptionName)
}
private async removeRoleFromSubscriptionUsers(
subscriptionId: number,
subscriptionName: SubscriptionName,
): Promise<void> {
private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
for (const userSubscription of userSubscriptions) {
await this.roleService.removeUserRole(await userSubscription.user, subscriptionName)
@@ -1,4 +1,3 @@
import { SubscriptionName } from '@standardnotes/common'
import { DomainEventHandlerInterface, SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -65,7 +64,7 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
)
}
private async addUserRole(user: User, subscriptionName: SubscriptionName): Promise<void> {
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
await this.roleService.addUserRole(user, subscriptionName)
}
@@ -1,4 +1,3 @@
import { SubscriptionName } from '@standardnotes/common'
import { DomainEventHandlerInterface, SubscriptionReassignedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -62,7 +61,7 @@ export class SubscriptionReassignedEventHandler implements DomainEventHandlerInt
)
}
private async addUserRole(user: User, subscriptionName: SubscriptionName): Promise<void> {
private async addUserRole(user: User, subscriptionName: string): Promise<void> {
await this.roleService.addUserRole(user, subscriptionName)
}
@@ -1,4 +1,3 @@
import { SubscriptionName } from '@standardnotes/common'
import { DomainEventHandlerInterface, SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -38,10 +37,7 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
await this.removeRoleFromSubscriptionUsers(event.payload.subscriptionId, event.payload.subscriptionName)
}
private async removeRoleFromSubscriptionUsers(
subscriptionId: number,
subscriptionName: SubscriptionName,
): Promise<void> {
private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
for (const userSubscription of userSubscriptions) {
await this.roleService.removeUserRole(await userSubscription.user, subscriptionName)
@@ -4,7 +4,6 @@ import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
import { SubscriptionName } from '@standardnotes/common'
import { RoleServiceInterface } from '../Role/RoleServiceInterface'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { Logger } from 'winston'
@@ -61,7 +60,7 @@ export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterf
await this.addRoleToSubscriptionUsers(event.payload.subscriptionId, event.payload.subscriptionName)
}
private async addRoleToSubscriptionUsers(subscriptionId: number, subscriptionName: SubscriptionName): Promise<void> {
private async addRoleToSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
for (const userSubscription of userSubscriptions) {
const user = await userSubscription.user
@@ -1,11 +1,10 @@
import { SubscriptionName } from '@standardnotes/common'
import { PermissionName } from '@standardnotes/features'
import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription'
import { User } from '../User/User'
export interface RoleServiceInterface {
addUserRole(user: User, subscriptionName: SubscriptionName): Promise<void>
addUserRole(user: User, subscriptionName: string): Promise<void>
setOfflineUserRole(offlineUserSubscription: OfflineUserSubscription): Promise<void>
removeUserRole(user: User, subscriptionName: SubscriptionName): Promise<void>
removeUserRole(user: User, subscriptionName: string): Promise<void>
userHasPermission(userUuid: string, permissionName: PermissionName): Promise<boolean>
}
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { RevokedSession } from './RevokedSession'
export interface RevokedSessionRepositoryInterface {
@@ -6,5 +5,5 @@ export interface RevokedSessionRepositoryInterface {
findAllByUserUuid(userUuid: string): Promise<Array<RevokedSession>>
save(revokedSession: RevokedSession): Promise<RevokedSession>
remove(revokedSession: RevokedSession): Promise<RevokedSession>
clearUserAgentByUserUuid(userUuid: Uuid): Promise<void>
clearUserAgentByUserUuid(userUuid: string): Promise<void>
}
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { Session } from './Session'
export interface SessionRepositoryInterface {
@@ -12,5 +11,5 @@ export interface SessionRepositoryInterface {
updatedTokenExpirationDates(uuid: string, accessExpiration: Date, refreshExpiration: Date): Promise<void>
save(session: Session): Promise<Session>
remove(session: Session): Promise<Session>
clearUserAgentByUserUuid(userUuid: Uuid): Promise<void>
clearUserAgentByUserUuid(userUuid: string): Promise<void>
}
@@ -7,7 +7,6 @@ import { TimerInterface } from '@standardnotes/time'
import { Logger } from 'winston'
import { LogSessionUserAgentOption, SettingName } from '@standardnotes/settings'
import { SessionBody } from '@standardnotes/responses'
import { Uuid } from '@standardnotes/common'
import { CryptoNode } from '@standardnotes/sncrypto-node'
import TYPES from '../../Bootstrap/Types'
@@ -226,7 +225,7 @@ export class SessionService implements SessionServiceInterface {
return this.revokedSessionRepository.save(revokedSession)
}
async deleteSessionByToken(token: string): Promise<Uuid | null> {
async deleteSessionByToken(token: string): Promise<string | null> {
const session = await this.getSessionFromToken(token)
if (session) {
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { SessionBody } from '@standardnotes/responses'
import { User } from '../User/User'
import { RevokedSession } from './RevokedSession'
@@ -21,7 +20,7 @@ export interface SessionServiceInterface {
getSessionFromToken(token: string): Promise<Session | undefined>
getRevokedSessionFromToken(token: string): Promise<RevokedSession | null>
markRevokedSessionAsReceived(revokedSession: RevokedSession): Promise<RevokedSession>
deleteSessionByToken(token: string): Promise<Uuid | null>
deleteSessionByToken(token: string): Promise<string | null>
isRefreshTokenValid(session: Session, token: string): boolean
getDeviceInfo(session: Session): string
getOperatingSystemInfoFromUserAgent(userAgent: string): string
@@ -1,6 +1,4 @@
import { Uuid } from '@standardnotes/common'
export type DeleteSettingDto = {
settingName: string
userUuid: Uuid
userUuid: string
}
@@ -1,8 +1,7 @@
import { Uuid } from '@standardnotes/common'
import { SettingName } from '@standardnotes/settings'
export type FindSettingDTO = {
userUuid: string
settingName: SettingName
settingUuid?: Uuid
settingUuid?: string
}
@@ -1,9 +1,8 @@
import { Uuid } from '@standardnotes/common'
import { SubscriptionSettingName } from '@standardnotes/settings'
export type FindSubscriptionSettingDTO = {
userUuid: Uuid
userSubscriptionUuid: Uuid
userUuid: string
userSubscriptionUuid: string
subscriptionSettingName: SubscriptionSettingName
settingUuid?: Uuid
settingUuid?: string
}
@@ -1,7 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { Setting } from './Setting'
import { SubscriptionSetting } from './SubscriptionSetting'
export interface SettingDecrypterInterface {
decryptSettingValue(setting: Setting | SubscriptionSetting, userUuid: Uuid): Promise<string | null>
decryptSettingValue(setting: Setting | SubscriptionSetting, userUuid: string): Promise<string | null>
}
@@ -1,4 +1,4 @@
import { SubscriptionName, Uuid } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionSettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
@@ -34,7 +34,7 @@ export class SubscriptionSettingService implements SubscriptionSettingServiceInt
async applyDefaultSubscriptionSettingsForSubscription(
userSubscription: UserSubscription,
subscriptionName: SubscriptionName,
userUuid: Uuid,
userUuid: string,
): Promise<void> {
const defaultSettingsWithValues =
await this.subscriptionSettingAssociationService.getDefaultSettingsAndValuesForSubscriptionName(subscriptionName)
@@ -129,8 +129,8 @@ export class SubscriptionSettingService implements SubscriptionSettingServiceInt
private async findPreviousSubscriptionSetting(
settingName: SubscriptionSettingName,
currentUserSubscriptionUuid: Uuid,
userUuid: Uuid,
currentUserSubscriptionUuid: string,
userUuid: string,
): Promise<SubscriptionSetting | null> {
const userSubscriptions = await this.userSubscriptionRepository.findByUserUuid(userUuid)
const previousSubscriptions = userSubscriptions.filter(
@@ -1,4 +1,3 @@
import { SubscriptionName, Uuid } from '@standardnotes/common'
import { UserSubscription } from '../Subscription/UserSubscription'
import { CreateOrReplaceSubscriptionSettingDTO } from './CreateOrReplaceSubscriptionSettingDTO'
@@ -9,8 +8,8 @@ import { SubscriptionSetting } from './SubscriptionSetting'
export interface SubscriptionSettingServiceInterface {
applyDefaultSubscriptionSettingsForSubscription(
userSubscription: UserSubscription,
subscriptionName: SubscriptionName,
userUuid: Uuid,
subscriptionName: string,
userUuid: string,
): Promise<void>
createOrReplace(dto: CreateOrReplaceSubscriptionSettingDTO): Promise<CreateOrReplaceSubscriptionSettingResponse>
findSubscriptionSettingWithDecryptedValue(dto: FindSubscriptionSettingDTO): Promise<SubscriptionSetting | null>
@@ -1,15 +1,14 @@
import { Uuid } from '@standardnotes/common'
import { InvitationStatus } from './InvitationStatus'
import { SharedSubscriptionInvitation } from './SharedSubscriptionInvitation'
export interface SharedSubscriptionInvitationRepositoryInterface {
save(sharedSubscriptionInvitation: SharedSubscriptionInvitation): Promise<SharedSubscriptionInvitation>
findOneByUuidAndStatus(uuid: Uuid, status: InvitationStatus): Promise<SharedSubscriptionInvitation | null>
findOneByUuid(uuid: Uuid): Promise<SharedSubscriptionInvitation | null>
findOneByUuidAndStatus(uuid: string, status: InvitationStatus): Promise<SharedSubscriptionInvitation | null>
findOneByUuid(uuid: string): Promise<SharedSubscriptionInvitation | null>
findByInviterEmail(inviterEmail: string): Promise<SharedSubscriptionInvitation[]>
findOneByInviteeAndInviterEmail(
inviteeEmail: string,
inviterEmail: string,
): Promise<SharedSubscriptionInvitation | null>
countByInviterEmailAndStatus(inviterEmail: Uuid, statuses: InvitationStatus[]): Promise<number>
countByInviterEmailAndStatus(inviterEmail: string, statuses: InvitationStatus[]): Promise<number>
}
@@ -1,8 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { SubscriptionToken } from './SubscriptionToken'
export interface SubscriptionTokenRepositoryInterface {
save(subscriptionToken: SubscriptionToken): Promise<boolean>
getUserUuidByToken(token: string): Promise<Uuid | undefined>
getUserUuidByToken(token: string): Promise<string | undefined>
}
@@ -1,13 +1,12 @@
import { Uuid } from '@standardnotes/common'
import { UserSubscription } from './UserSubscription'
import { UserSubscriptionType } from './UserSubscriptionType'
export interface UserSubscriptionRepositoryInterface {
findOneByUuid(uuid: Uuid): Promise<UserSubscription | null>
countByUserUuid(userUuid: Uuid): Promise<number>
findOneByUserUuid(userUuid: Uuid): Promise<UserSubscription | null>
findByUserUuid(userUuid: Uuid): Promise<UserSubscription[]>
findOneByUserUuidAndSubscriptionId(userUuid: Uuid, subscriptionId: number): Promise<UserSubscription | null>
findOneByUuid(uuid: string): Promise<UserSubscription | null>
countByUserUuid(userUuid: string): Promise<number>
findOneByUserUuid(userUuid: string): Promise<UserSubscription | null>
findByUserUuid(userUuid: string): Promise<UserSubscription[]>
findOneByUserUuidAndSubscriptionId(userUuid: string, subscriptionId: number): Promise<UserSubscription | null>
findBySubscriptionIdAndType(subscriptionId: number, type: UserSubscriptionType): Promise<UserSubscription[]>
findBySubscriptionId(subscriptionId: number): Promise<UserSubscription[]>
updateEndsAt(subscriptionId: number, endsAt: number, updatedAt: number): Promise<void>
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
@@ -21,7 +20,7 @@ export class UserSubscriptionService implements UserSubscriptionServiceInterface
return this.findRegularSubscription(userSubscription)
}
async findRegularSubscriptionForUuid(uuid: Uuid): Promise<FindRegularSubscriptionResponse> {
async findRegularSubscriptionForUuid(uuid: string): Promise<FindRegularSubscriptionResponse> {
const userSubscription = await this.userSubscriptionRepository.findOneByUuid(uuid)
return this.findRegularSubscription(userSubscription)
@@ -1,7 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { FindRegularSubscriptionResponse } from './FindRegularSubscriptionResponse'
export interface UserSubscriptionServiceInterface {
findRegularSubscriptionForUuid(uuid: Uuid): Promise<FindRegularSubscriptionResponse>
findRegularSubscriptionForUserUuid(userUuid: Uuid): Promise<FindRegularSubscriptionResponse>
findRegularSubscriptionForUuid(uuid: string): Promise<FindRegularSubscriptionResponse>
findRegularSubscriptionForUserUuid(userUuid: string): Promise<FindRegularSubscriptionResponse>
}
@@ -1,6 +1,4 @@
import { Uuid } from '@standardnotes/common'
export type CancelSharedSubscriptionInvitationDTO = {
sharedSubscriptionInvitationUuid: Uuid
sharedSubscriptionInvitationUuid: string
inviterEmail: string
}
@@ -1,4 +1,4 @@
import { Either, Uuid } from '@standardnotes/common'
import { Either } from '@standardnotes/common'
import { Session } from '../../Session/Session'
import { User } from '../../User/User'
@@ -8,6 +8,6 @@ export type CreateCrossServiceTokenDTO = Either<
session?: Session
},
{
userUuid: Uuid
userUuid: string
}
>
@@ -1,7 +1,5 @@
import { Uuid } from '@standardnotes/common'
export type DeleteSettingDto = {
userUuid: Uuid
userUuid: string
settingName: string
uuid?: string
timestamp?: number
@@ -1,9 +1,7 @@
import { Uuid } from '@standardnotes/common'
export type DeleteSettingResponse =
| {
success: true
userUuid: Uuid
userUuid: string
settingName: string
}
| {
@@ -1,7 +1,5 @@
import { Uuid } from '@standardnotes/common'
export type GetSettingDto = {
userUuid: Uuid
userUuid: string
settingName: string
allowSensitiveRetrieval?: boolean
}
@@ -1,11 +1,9 @@
import { Uuid } from '@standardnotes/common'
import { SimpleSetting } from '../../Setting/SimpleSetting'
export type GetSettingResponse =
| {
success: true
userUuid: Uuid
userUuid: string
setting: SimpleSetting
}
| {
@@ -1,7 +1,5 @@
import { Uuid } from '@standardnotes/common'
export type GetSettingsDto = {
userUuid: Uuid
userUuid: string
settingName?: string
allowSensitiveRetrieval?: boolean
updatedAfter?: number
@@ -1,11 +1,9 @@
import { Uuid } from '@standardnotes/common'
import { SimpleSetting } from '../../Setting/SimpleSetting'
export type GetSettingsResponse =
| {
success: true
userUuid: Uuid
userUuid: string
settings: SimpleSetting[]
}
| {
@@ -1,8 +1,7 @@
import { Uuid } from '@standardnotes/common'
import { SubscriptionSettingName } from '@standardnotes/settings'
export type GetSubscriptionSettingDTO = {
userUuid: Uuid
userUuid: string
subscriptionSettingName: SubscriptionSettingName
allowSensitiveRetrieval?: boolean
}
@@ -1,5 +1,7 @@
import 'reflect-metadata'
import { FeatureDescription } from '@standardnotes/features'
import { RoleName } from '@standardnotes/domain-core'
import { GetUserFeatures } from './GetUserFeatures'
import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
import { User } from '../../User/User'
@@ -21,7 +23,9 @@ describe('GetUserFeatures', () => {
feature1 = { name: 'foobar' } as jest.Mocked<FeatureDescription>
featureService = {} as jest.Mocked<FeatureServiceInterface>
featureService.getFeaturesForUser = jest.fn().mockReturnValue([feature1])
featureService.getFeaturesForOfflineUser = jest.fn().mockReturnValue([feature1])
featureService.getFeaturesForOfflineUser = jest
.fn()
.mockReturnValue({ features: [feature1], roles: [RoleName.NAMES.ProUser] })
})
it('should fail if a user is not found', async () => {
@@ -50,11 +54,8 @@ describe('GetUserFeatures', () => {
it('should return offline user features', async () => {
expect(await createUseCase().execute({ email: 'test@test.com', offline: true })).toEqual({
success: true,
features: [
{
name: 'foobar',
},
],
features: [{ name: 'foobar' }],
roles: [RoleName.NAMES.ProUser],
})
})
})
@@ -15,11 +15,12 @@ export class GetUserFeatures implements UseCaseInterface {
async execute(dto: GetUserFeaturesDto): Promise<GetUserFeaturesResponse> {
if (dto.offline) {
const userFeatures = await this.featureService.getFeaturesForOfflineUser(dto.email)
const { features, roles } = await this.featureService.getFeaturesForOfflineUser(dto.email)
return {
success: true,
features: userFeatures,
features,
roles,
}
}
@@ -1,8 +1,6 @@
import { Uuid } from '@standardnotes/common'
export type GetUserFeaturesDto =
| {
userUuid: Uuid
userUuid: string
offline: false
}
| {
@@ -4,6 +4,7 @@ export type GetUserFeaturesResponse =
| {
success: true
features: FeatureDescription[]
roles?: string[]
userUuid?: string
}
| {
@@ -1,5 +1,3 @@
import { Uuid } from '@standardnotes/common'
export type GetUserSubscriptionDto = {
userUuid: Uuid
userUuid: string
}
@@ -1,8 +1,6 @@
import { Uuid } from '@standardnotes/common'
export type InviteToSharedSubscriptionDTO = {
inviterEmail: string
inviterUuid: Uuid
inviterUuid: string
inviterRoles: string[]
inviteeIdentifier: string
}
@@ -1,9 +1,7 @@
import { Uuid } from '@standardnotes/common'
export type InviteToSharedSubscriptionResult =
| {
success: true
sharedSubscriptionInvitationUuid: Uuid
sharedSubscriptionInvitationUuid: string
}
| {
success: false
@@ -1,7 +1,7 @@
import { UserRequestType, Uuid } from '@standardnotes/common'
import { UserRequestType } from '@standardnotes/common'
export type ProcessUserRequestDTO = {
userUuid: Uuid
userUuid: string
userEmail: string
requestType: UserRequestType
}
@@ -1,8 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { SettingProps } from '../../Setting/SettingProps'
export type UpdateSettingDto = {
userUuid: Uuid
userUuid: string
props: SettingProps
}
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { PredicateName, PredicateVerificationResult } from '@standardnotes/predicates'
import { EmailBackupFrequency, SettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'
@@ -33,13 +32,13 @@ export class VerifyPredicate implements UseCaseInterface {
}
}
private async hasUserBoughtASubscription(userUuid: Uuid): Promise<boolean> {
private async hasUserBoughtASubscription(userUuid: string): Promise<boolean> {
const subscription = await this.userSubscriptionRepository.findOneByUserUuid(userUuid)
return subscription !== null
}
private async hasUserEnabledEmailBackups(userUuid: Uuid): Promise<boolean> {
private async hasUserEnabledEmailBackups(userUuid: string): Promise<boolean> {
const setting = await this.settingRepository.findOneByNameAndUserUuid(SettingName.EmailBackupFrequency, userUuid)
if (setting === null || setting.value === EmailBackupFrequency.Disabled) {
@@ -1,7 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { Predicate } from '@standardnotes/predicates'
export type VerifyPredicateDTO = {
predicate: Predicate
userUuid: Uuid
userUuid: string
}
@@ -1,4 +1,3 @@
import { Uuid } from '@standardnotes/common'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm'
@@ -34,7 +33,7 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
.getMany()
}
async countByUserUuid(userUuid: Uuid): Promise<number> {
async countByUserUuid(userUuid: string): Promise<number> {
return await this.ormRepository
.createQueryBuilder()
.where('user_uuid = :user_uuid', {
@@ -47,7 +46,7 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
return this.ormRepository.save(subscription)
}
async findOneByUserUuidAndSubscriptionId(userUuid: Uuid, subscriptionId: number): Promise<UserSubscription | null> {
async findOneByUserUuidAndSubscriptionId(userUuid: string, subscriptionId: number): Promise<UserSubscription | null> {
return await this.ormRepository
.createQueryBuilder()
.where('user_uuid = :userUuid AND subscription_id = :subscriptionId', {
@@ -78,7 +77,7 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
.getMany()
}
async findOneByUuid(uuid: Uuid): Promise<UserSubscription | null> {
async findOneByUuid(uuid: string): Promise<UserSubscription | null> {
return await this.ormRepository
.createQueryBuilder()
.where('uuid = :uuid', {
@@ -87,7 +86,7 @@ export class MySQLUserSubscriptionRepository implements UserSubscriptionReposito
.getOne()
}
async findOneByUserUuid(userUuid: Uuid): Promise<UserSubscription | null> {
async findOneByUserUuid(userUuid: string): Promise<UserSubscription | null> {
const subscriptions = await this.ormRepository
.createQueryBuilder()
.where('user_uuid = :user_uuid', {
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.46.4](https://github.com/standardnotes/server/compare/@standardnotes/common@1.46.3...@standardnotes/common@1.46.4) (2023-01-20)
**Note:** Version bump only for package @standardnotes/common
## [1.46.3](https://github.com/standardnotes/server/compare/@standardnotes/common@1.46.2...@standardnotes/common@1.46.3) (2023-01-19)
**Note:** Version bump only for package @standardnotes/common
## [1.46.2](https://github.com/standardnotes/server/compare/@standardnotes/common@1.46.1...@standardnotes/common@1.46.2) (2023-01-19)
**Note:** Version bump only for package @standardnotes/common
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/common",
"version": "1.46.2",
"version": "1.46.4",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -25,7 +25,7 @@
"devDependencies": {
"@types/jest": "^29.1.1",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.1.2",
"ts-jest": "^29.0.3",
@@ -1 +0,0 @@
export type Uuid = string
@@ -1,34 +0,0 @@
import { UuidValidator } from './UuidValidator'
describe('UuidValidator', () => {
const createValidator = () => new UuidValidator()
const validUuids = [
'2221101c-1da9-4d2b-9b32-b8be2a8d1c82',
'c08f2f29-a74b-42b4-aefd-98af9832391c',
'b453fa64-1493-443b-b5bb-bca7b9c696c7',
]
const invalidUuids = [
123,
'someone@127.0.0.1',
'',
null,
'b453fa64-1493-443b-b5bb-ca7b9c696c7',
'c08f*f29-a74b-42b4-aefd-98af9832391c',
'c08f*f29-a74b-42b4-aefd-98af9832391c',
'../../escaped.sh',
]
it('should validate proper uuids', () => {
for (const validUuid of validUuids) {
expect(createValidator().validate(validUuid)).toBeTruthy()
}
})
it('should not validate invalid uuids', () => {
for (const invalidUuid of invalidUuids) {
expect(createValidator().validate(invalidUuid as string)).toBeFalsy()
}
})
})
@@ -1,10 +0,0 @@
import { Uuid } from '../DataType/Uuid'
import { ValidatorInterface } from './ValidatorInterface'
export class UuidValidator implements ValidatorInterface<Uuid> {
private readonly UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i
validate(data: Uuid): boolean {
return String(data).toLowerCase().match(this.UUID_REGEX) !== null
}
}
@@ -1,3 +0,0 @@
export interface ValidatorInterface<T> {
validate(data: T): boolean
}

Some files were not shown because too many files have changed in this diff Show More