mirror of
https://github.com/standardnotes/server
synced 2026-01-19 20:04:28 -05:00
Compare commits
19 Commits
@standardn
...
@standardn
| 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.
BIN
.yarn/cache/@eslint-eslintrc-npm-1.4.1-007f670de2-4e469ed508.zip
vendored
Normal file
BIN
.yarn/cache/@eslint-eslintrc-npm-1.4.1-007f670de2-4e469ed508.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@humanwhocodes-config-array-npm-0.11.8-7955bfecc2-010892ba3c.zip
vendored
Normal file
BIN
.yarn/cache/@humanwhocodes-config-array-npm-0.11.8-7955bfecc2-010892ba3c.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-eslint-plugin-npm-5.48.2-4f86b96814-773d1b78d4.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-eslint-plugin-npm-5.48.2-4f86b96814-773d1b78d4.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-scope-manager-npm-5.48.2-9a72dae708-788edc410b.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-scope-manager-npm-5.48.2-9a72dae708-788edc410b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-types-npm-5.48.2-bdebd4d2d7-8842362cca.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-types-npm-5.48.2-bdebd4d2d7-8842362cca.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-typescript-estree-npm-5.48.2-2166870a0a-6d3da2b252.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-typescript-estree-npm-5.48.2-2166870a0a-6d3da2b252.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-utils-npm-5.48.2-0126c67a53-f2f51f1bf6.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-utils-npm-5.48.2-0126c67a53-f2f51f1bf6.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@typescript-eslint-visitor-keys-npm-5.48.2-b644f53ee6-7a4ea8035b.zip
vendored
Normal file
BIN
.yarn/cache/@typescript-eslint-visitor-keys-npm-5.48.2-b644f53ee6-7a4ea8035b.zip
vendored
Normal file
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
.yarn/cache/globals-npm-13.19.0-a63c75a2dd-3f3d6606b7.zip
vendored
Normal file
BIN
.yarn/cache/globals-npm-13.19.0-a63c75a2dd-3f3d6606b7.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/natural-compare-lite-npm-1.4.0-12b6b308ed-e554405686.zip
vendored
Normal file
BIN
.yarn/cache/natural-compare-lite-npm-1.4.0-12b6b308ed-e554405686.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
|
||||
@@ -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', {
|
||||
|
||||
@@ -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