mirror of
https://github.com/standardnotes/server
synced 2026-04-19 17:02:25 -04:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f4776b52b | |||
| d20f03127a | |||
| 4b6c7774e0 | |||
| d02bca8879 | |||
| 5e654ccf94 | |||
| 7d3e5c22fb | |||
| 23eb61ee5f | |||
| 2cded4b2d1 | |||
| ba7662fc1e | |||
| 832a48ac76 | |||
| 2db0c125fe | |||
| 20d9624bc6 | |||
| f20ee68f50 | |||
| cbf45ce3eb | |||
| 2e7fdd93dd | |||
| 8ce38f82b5 | |||
| ec5429eeec | |||
| 4b17c4045d | |||
| aaf42e4693 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
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
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
+3
-4
@@ -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
-3
@@ -1,6 +1,4 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type CancelSharedSubscriptionInvitationDTO = {
|
||||
sharedSubscriptionInvitationUuid: Uuid
|
||||
sharedSubscriptionInvitationUuid: string
|
||||
inviterEmail: string
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
-2
@@ -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
-3
@@ -1,8 +1,6 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type InviteToSharedSubscriptionDTO = {
|
||||
inviterEmail: string
|
||||
inviterUuid: Uuid
|
||||
inviterUuid: string
|
||||
inviterRoles: string[]
|
||||
inviteeIdentifier: string
|
||||
}
|
||||
|
||||
+1
-3
@@ -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', {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user