mirror of
https://github.com/standardnotes/server
synced 2026-01-31 20:01:14 -05:00
Compare commits
17 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25f752d6b5 | ||
|
|
74e35a2d65 | ||
|
|
3532289575 | ||
|
|
7db9ba03f3 | ||
|
|
b0baaf9ea6 | ||
|
|
b7c6dab3ad | ||
|
|
2daa145867 | ||
|
|
4bd5fb22b4 | ||
|
|
78533a6045 | ||
|
|
e1c533a15e | ||
|
|
b6c2bb8023 | ||
|
|
c45653a50a | ||
|
|
d827513b73 | ||
|
|
ad183ca621 | ||
|
|
1d11c5a186 | ||
|
|
e84e78ec55 | ||
|
|
f91e4316ff |
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.21.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.21.2...@standardnotes/analytics@2.21.3) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.21.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.21.1...@standardnotes/analytics@2.21.2) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.21.2",
|
||||
"version": "2.21.3",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.49.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.49.5...@standardnotes/api-gateway@1.49.6) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.49.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.49.4...@standardnotes/api-gateway@1.49.5) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.49.5",
|
||||
"version": "1.49.6",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,53 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.93.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.7...@standardnotes/auth-server@1.93.8) (2023-03-10)
|
||||
|
||||
### Reverts
|
||||
|
||||
* Revert "fix(auth): change supported algorithms on authenticator registration options" ([74e35a2](https://github.com/standardnotes/server/commit/74e35a2d659f13def87869df29e863a2ce32910c))
|
||||
|
||||
## [1.93.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.6...@standardnotes/auth-server@1.93.7) (2023-03-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** change supported algorithms on authenticator registration options ([7db9ba0](https://github.com/standardnotes/server/commit/7db9ba03f3c14b83dc4344935499f48db800c87d))
|
||||
|
||||
## [1.93.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.5...@standardnotes/auth-server@1.93.6) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.93.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.4...@standardnotes/auth-server@1.93.5) (2023-03-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** remove migrate email settings procedure ([4bd5fb2](https://github.com/standardnotes/server/commit/4bd5fb22b447b0e0fdb136aa46ddc812c8b272cd))
|
||||
|
||||
## [1.93.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.3...@standardnotes/auth-server@1.93.4) (2023-03-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** change response from verifying authenticator registration ([e1c533a](https://github.com/standardnotes/server/commit/e1c533a15e33e215e90fbe15d2d4994605eaa1bd))
|
||||
|
||||
## [1.93.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.2...@standardnotes/auth-server@1.93.3) (2023-03-09)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** migrate encrypted sign in settings ([d827513](https://github.com/standardnotes/server/commit/d827513b73a57fbdb72c3112f32dc2a296103450))
|
||||
* **auth:** remove authenticator names from server ([c45653a](https://github.com/standardnotes/server/commit/c45653a50a9d25de1e0fc86127ff6931dc98406d))
|
||||
|
||||
## [1.93.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.1...@standardnotes/auth-server@1.93.2) (2023-03-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** authentication options ([1d11c5a](https://github.com/standardnotes/server/commit/1d11c5a1865f81ca57d0ad4313cc3df497b4c445))
|
||||
|
||||
## [1.93.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.93.0...@standardnotes/auth-server@1.93.1) (2023-03-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** migrate muted email notifications settings ([f91e431](https://github.com/standardnotes/server/commit/f91e4316ff4993d032c016bb233b93a9f3356cf3))
|
||||
|
||||
# [1.93.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.92.0...@standardnotes/auth-server@1.93.0) (2023-03-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import 'newrelic'
|
||||
|
||||
import { Stream } from 'stream'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
|
||||
import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface'
|
||||
import { SettingName } from '@standardnotes/settings'
|
||||
import { EmailLevel } from '@standardnotes/domain-core'
|
||||
import { UserSubscriptionServiceInterface } from '../src/Domain/Subscription/UserSubscriptionServiceInterface'
|
||||
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
|
||||
import { SubscriptionSettingServiceInterface } from '../src/Domain/Setting/SubscriptionSettingServiceInterface'
|
||||
import { EncryptionVersion } from '../src/Domain/Encryption/EncryptionVersion'
|
||||
|
||||
const requestSettingMigration = async (
|
||||
settingRepository: SettingRepositoryInterface,
|
||||
subscriptionSettingService: SubscriptionSettingServiceInterface,
|
||||
userRepository: UserRepositoryInterface,
|
||||
userSubscriptionService: UserSubscriptionServiceInterface,
|
||||
domainEventFactory: DomainEventFactoryInterface,
|
||||
domainEventPublisher: DomainEventPublisherInterface,
|
||||
): Promise<void> => {
|
||||
const stream = await settingRepository.streamAllByNameAndValue(
|
||||
SettingName.create(SettingName.NAMES.MuteSignInEmails).getValue(),
|
||||
'not_muted',
|
||||
)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
stream
|
||||
.pipe(
|
||||
new Stream.Transform({
|
||||
objectMode: true,
|
||||
transform: async (setting, _encoding, callback) => {
|
||||
const user = await userRepository.findOneByUuid(setting.setting_user_uuid)
|
||||
if (!user) {
|
||||
callback()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const { regularSubscription, sharedSubscription } =
|
||||
await userSubscriptionService.findRegularSubscriptionForUserUuid(user.uuid)
|
||||
|
||||
const subscription = sharedSubscription ?? regularSubscription
|
||||
if (!subscription) {
|
||||
await domainEventPublisher.publish(
|
||||
domainEventFactory.createMuteEmailsSettingChangedEvent({
|
||||
username: user.email,
|
||||
mute: true,
|
||||
emailSubscriptionRejectionLevel: EmailLevel.LEVELS.SignIn,
|
||||
}),
|
||||
)
|
||||
|
||||
await settingRepository.deleteByUserUuid({
|
||||
userUuid: user.uuid,
|
||||
settingName: SettingName.NAMES.MuteSignInEmails,
|
||||
})
|
||||
|
||||
callback()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await subscriptionSettingService.createOrReplace({
|
||||
userSubscription: subscription,
|
||||
props: {
|
||||
name: SettingName.NAMES.MuteSignInEmails,
|
||||
sensitive: false,
|
||||
serverEncryptionVersion: EncryptionVersion.Unencrypted,
|
||||
unencryptedValue: 'not_muted',
|
||||
},
|
||||
})
|
||||
|
||||
await settingRepository.deleteByUserUuid({
|
||||
userUuid: user.uuid,
|
||||
settingName: SettingName.NAMES.MuteSignInEmails,
|
||||
})
|
||||
|
||||
callback()
|
||||
},
|
||||
}),
|
||||
)
|
||||
.on('finish', resolve)
|
||||
.on('error', reject)
|
||||
})
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
void container.load().then((container) => {
|
||||
dayjs.extend(utc)
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const logger: Logger = container.get(TYPES.Logger)
|
||||
|
||||
logger.info('Starting migration of mute sign in emails settings to subscription settings...')
|
||||
|
||||
const settingRepository: SettingRepositoryInterface = container.get(TYPES.SettingRepository)
|
||||
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
|
||||
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
|
||||
const subscriptionSettingService: SubscriptionSettingServiceInterface = container.get(
|
||||
TYPES.SubscriptionSettingService,
|
||||
)
|
||||
const userRepository: UserRepositoryInterface = container.get(TYPES.UserRepository)
|
||||
const userSubscriptionService: UserSubscriptionServiceInterface = container.get(TYPES.UserSubscriptionService)
|
||||
|
||||
Promise.resolve(
|
||||
requestSettingMigration(
|
||||
settingRepository,
|
||||
subscriptionSettingService,
|
||||
userRepository,
|
||||
userSubscriptionService,
|
||||
domainEventFactory,
|
||||
domainEventPublisher,
|
||||
),
|
||||
)
|
||||
.then(() => {
|
||||
logger.info('Migration of mute sign in emails settings to subscription settings finished successfully.')
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Migration of mute sign in emails settings to subscription settings failed: ${error.message}`)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
@@ -1,11 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const pnp = require(path.normalize(path.resolve(__dirname, '../../..', '.pnp.cjs'))).setup()
|
||||
|
||||
const index = require(path.normalize(path.resolve(__dirname, '../dist/bin/migrate_email_settings.js')))
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
|
||||
exports.default = index
|
||||
@@ -40,11 +40,6 @@ case "$COMMAND" in
|
||||
node docker/entrypoint-user-email-backup.js $EMAIL
|
||||
;;
|
||||
|
||||
'migrate-email-settings' )
|
||||
echo "[Docker] Starting Email Settings Migration..."
|
||||
node docker/entrypoint-migrate-email-settings.js
|
||||
;;
|
||||
|
||||
'dropbox-daily-backup' )
|
||||
echo "[Docker] Starting Dropbox Daily Backup..."
|
||||
node docker/entrypoint-backup.js dropbox daily
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm'
|
||||
|
||||
export class removeAuthenticatorNamesFromServer1678340701766 implements MigrationInterface {
|
||||
name = 'removeAuthenticatorNamesFromServer1678340701766'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query('ALTER TABLE `authenticators` DROP COLUMN `name`')
|
||||
}
|
||||
|
||||
public async down(): Promise<void> {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.93.0",
|
||||
"version": "1.93.8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -88,7 +88,6 @@ export class AuthenticatorsController {
|
||||
): Promise<HttpResponse<VerifyAuthenticatorRegistrationResponseResponseBody>> {
|
||||
const result = await this.verifyAuthenticatorRegistrationResponse.execute({
|
||||
userUuid: params.userUuid,
|
||||
name: params.name,
|
||||
attestationResponse: params.attestationResponse,
|
||||
})
|
||||
|
||||
@@ -105,7 +104,7 @@ export class AuthenticatorsController {
|
||||
|
||||
return {
|
||||
status: HttpStatusCode.Success,
|
||||
data: { success: result.getValue() },
|
||||
data: { id: result.getValue().toString() },
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ describe('Authenticator', () => {
|
||||
it('should create an entity', () => {
|
||||
const entityOrError = Authenticator.create({
|
||||
counter: 1,
|
||||
name: 'my-key',
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialId: Buffer.from('credentialId'),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Dates, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface AuthenticatorProps {
|
||||
name: string
|
||||
userUuid: Uuid
|
||||
credentialId: Uint8Array
|
||||
credentialPublicKey: Uint8Array
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface SettingRepositoryInterface {
|
||||
findLastByNameAndUserUuid(name: string, userUuid: string): Promise<Setting | null>
|
||||
findAllByUserUuid(userUuid: string): Promise<Setting[]>
|
||||
streamAllByNameAndValue(name: SettingName, value: string): Promise<ReadStream>
|
||||
streamAllByName(name: SettingName): Promise<ReadStream>
|
||||
deleteByUserUuid(dto: DeleteSettingDto): Promise<void>
|
||||
save(setting: Setting): Promise<Setting>
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ describe('DeleteAuthenticator', () => {
|
||||
beforeEach(() => {
|
||||
authenticator = Authenticator.create({
|
||||
counter: 1,
|
||||
name: 'my-key',
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialId: Buffer.from('credentialId'),
|
||||
|
||||
@@ -24,7 +24,6 @@ describe('GenerateAuthenticatorAuthenticationOptions', () => {
|
||||
beforeEach(() => {
|
||||
const authenticator = Authenticator.create({
|
||||
counter: 1,
|
||||
name: 'my-key',
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialId: Buffer.from('credentialId'),
|
||||
@@ -54,7 +53,7 @@ describe('GenerateAuthenticatorAuthenticationOptions', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Could not generate authenticator registration options: Username cannot be empty')
|
||||
expect(result.getError()).toBe('Could not generate authenticator authentication options: Username cannot be empty')
|
||||
})
|
||||
|
||||
it('should return error if user uuid is not valid', async () => {
|
||||
@@ -70,7 +69,7 @@ describe('GenerateAuthenticatorAuthenticationOptions', () => {
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe(
|
||||
'Could not generate authenticator registration options: Given value is not a valid uuid: invalid',
|
||||
'Could not generate authenticator authentication options: Given value is not a valid uuid: invalid',
|
||||
)
|
||||
})
|
||||
|
||||
@@ -97,7 +96,7 @@ describe('GenerateAuthenticatorAuthenticationOptions', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Could not generate authenticator registration options: Oops')
|
||||
expect(result.getError()).toBe('Could not generate authenticator authentication options: Oops')
|
||||
|
||||
mock.mockRestore()
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ export class GenerateAuthenticatorAuthenticationOptions implements UseCaseInterf
|
||||
async execute(dto: GenerateAuthenticatorAuthenticationOptionsDTO): Promise<Result<Record<string, unknown>>> {
|
||||
const usernameOrError = Username.create(dto.username)
|
||||
if (usernameOrError.isFailed()) {
|
||||
return Result.fail(`Could not generate authenticator registration options: ${usernameOrError.getError()}`)
|
||||
return Result.fail(`Could not generate authenticator authentication options: ${usernameOrError.getError()}`)
|
||||
}
|
||||
const username = usernameOrError.getValue()
|
||||
|
||||
@@ -46,7 +46,7 @@ export class GenerateAuthenticatorAuthenticationOptions implements UseCaseInterf
|
||||
|
||||
const userUuidOrError = Uuid.create(user.uuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return Result.fail(`Could not generate authenticator registration options: ${userUuidOrError.getError()}`)
|
||||
return Result.fail(`Could not generate authenticator authentication options: ${userUuidOrError.getError()}`)
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
@@ -67,7 +67,7 @@ export class GenerateAuthenticatorAuthenticationOptions implements UseCaseInterf
|
||||
})
|
||||
if (authenticatorChallengeOrError.isFailed()) {
|
||||
return Result.fail(
|
||||
`Could not generate authenticator registration options: ${authenticatorChallengeOrError.getError()}`,
|
||||
`Could not generate authenticator authentication options: ${authenticatorChallengeOrError.getError()}`,
|
||||
)
|
||||
}
|
||||
const authenticatorChallenge = authenticatorChallengeOrError.getValue()
|
||||
|
||||
@@ -21,7 +21,6 @@ describe('GenerateAuthenticatorRegistrationOptions', () => {
|
||||
beforeEach(() => {
|
||||
const authenticator = Authenticator.create({
|
||||
counter: 1,
|
||||
name: 'my-key',
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialId: Buffer.from('credentialId'),
|
||||
|
||||
@@ -24,7 +24,6 @@ describe('VerifyAuthenticatorAuthenticationResponse', () => {
|
||||
beforeEach(() => {
|
||||
const authenticator = Authenticator.create({
|
||||
counter: 1,
|
||||
name: 'my-key',
|
||||
credentialBackedUp: true,
|
||||
credentialDeviceType: 'singleDevice',
|
||||
credentialId: Buffer.from('credentialId'),
|
||||
|
||||
@@ -38,7 +38,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: 'invalid',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -56,27 +55,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should return error if name is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: '',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
response: {
|
||||
attestationObject: Buffer.from('attestationObject'),
|
||||
clientDataJSON: Buffer.from('clientDataJSON'),
|
||||
},
|
||||
type: 'type',
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeTruthy()
|
||||
expect(result.getError()).toEqual('Could not verify authenticator registration response: Given value is empty: ')
|
||||
})
|
||||
|
||||
it('should return error if challenge is not found', async () => {
|
||||
authenticatorChallengeRepository.findByUserUuid = jest.fn().mockReturnValue(null)
|
||||
|
||||
@@ -84,7 +62,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -125,7 +102,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -159,7 +135,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -195,7 +170,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -245,7 +219,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
@@ -289,7 +262,6 @@ describe('VerifyAuthenticatorRegistrationResponse', () => {
|
||||
|
||||
const result = await useCase.execute({
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
name: 'name',
|
||||
attestationResponse: {
|
||||
id: Buffer.from('id'),
|
||||
rawId: Buffer.from('rawId'),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Dates, Result, UseCaseInterface, Uuid, Validator } from '@standardnotes/domain-core'
|
||||
import { Dates, Result, UniqueEntityId, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { VerifiedRegistrationResponse, verifyRegistrationResponse } from '@simplewebauthn/server'
|
||||
|
||||
import { AuthenticatorChallengeRepositoryInterface } from '../../Authenticator/AuthenticatorChallengeRepositoryInterface'
|
||||
@@ -6,7 +6,7 @@ import { AuthenticatorRepositoryInterface } from '../../Authenticator/Authentica
|
||||
import { Authenticator } from '../../Authenticator/Authenticator'
|
||||
import { VerifyAuthenticatorRegistrationResponseDTO } from './VerifyAuthenticatorRegistrationResponseDTO'
|
||||
|
||||
export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface<boolean> {
|
||||
export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface<UniqueEntityId> {
|
||||
constructor(
|
||||
private authenticatorRepository: AuthenticatorRepositoryInterface,
|
||||
private authenticatorChallengeRepository: AuthenticatorChallengeRepositoryInterface,
|
||||
@@ -15,18 +15,13 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
private requireUserVerification: boolean,
|
||||
) {}
|
||||
|
||||
async execute(dto: VerifyAuthenticatorRegistrationResponseDTO): Promise<Result<boolean>> {
|
||||
async execute(dto: VerifyAuthenticatorRegistrationResponseDTO): Promise<Result<UniqueEntityId>> {
|
||||
const userUuidOrError = Uuid.create(dto.userUuid)
|
||||
if (userUuidOrError.isFailed()) {
|
||||
return Result.fail(`Could not verify authenticator registration response: ${userUuidOrError.getError()}`)
|
||||
}
|
||||
const userUuid = userUuidOrError.getValue()
|
||||
|
||||
const nameValidation = Validator.isNotEmpty(dto.name)
|
||||
if (nameValidation.isFailed()) {
|
||||
return Result.fail(`Could not verify authenticator registration response: ${nameValidation.getError()}`)
|
||||
}
|
||||
|
||||
const authenticatorChallenge = await this.authenticatorChallengeRepository.findByUserUuid(userUuid)
|
||||
if (!authenticatorChallenge) {
|
||||
return Result.fail('Could not verify authenticator registration response: challenge not found')
|
||||
@@ -55,7 +50,6 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
|
||||
const authenticatorOrError = Authenticator.create({
|
||||
userUuid,
|
||||
name: dto.name,
|
||||
counter: verification.registrationInfo.counter,
|
||||
credentialBackedUp: verification.registrationInfo.credentialBackedUp,
|
||||
credentialDeviceType: verification.registrationInfo.credentialDeviceType,
|
||||
@@ -71,6 +65,6 @@ export class VerifyAuthenticatorRegistrationResponse implements UseCaseInterface
|
||||
|
||||
await this.authenticatorRepository.save(authenticator)
|
||||
|
||||
return Result.ok(true)
|
||||
return Result.ok(authenticator.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export interface VerifyAuthenticatorRegistrationResponseDTO {
|
||||
userUuid: string
|
||||
name: string
|
||||
attestationResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
export interface AuthenticatorHttpProjection {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export interface VerifyAuthenticatorRegistrationResponseRequestParams {
|
||||
userUuid: string
|
||||
name: string
|
||||
attestationResponse: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export interface VerifyAuthenticatorRegistrationResponseResponseBody {
|
||||
success: boolean
|
||||
id: string
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ export class InversifyExpressAuthenticatorsController extends BaseHttpController
|
||||
const result = await this.authenticatorsController.verifyRegistrationResponse({
|
||||
userUuid: response.locals.user.uuid,
|
||||
attestationResponse: request.body.attestationResponse,
|
||||
name: request.body.name,
|
||||
})
|
||||
|
||||
return this.json(result.data, result.status)
|
||||
|
||||
@@ -29,6 +29,16 @@ export class MySQLSettingRepository implements SettingRepositoryInterface {
|
||||
.getOne()
|
||||
}
|
||||
|
||||
async streamAllByName(name: SettingName): Promise<ReadStream> {
|
||||
return this.ormRepository
|
||||
.createQueryBuilder('setting')
|
||||
.where('setting.name = :name', {
|
||||
name: name.value,
|
||||
})
|
||||
.orderBy('updated_at', 'ASC')
|
||||
.stream()
|
||||
}
|
||||
|
||||
async streamAllByNameAndValue(name: SettingName, value: string): Promise<ReadStream> {
|
||||
return this.ormRepository
|
||||
.createQueryBuilder('setting')
|
||||
|
||||
@@ -11,13 +11,6 @@ export class TypeORMAuthenticator {
|
||||
})
|
||||
declare userUuid: string
|
||||
|
||||
@Column({
|
||||
name: 'name',
|
||||
type: 'varchar',
|
||||
length: 255,
|
||||
})
|
||||
declare name: string
|
||||
|
||||
@Column({
|
||||
name: 'credential_id',
|
||||
type: 'text',
|
||||
|
||||
@@ -11,7 +11,6 @@ export class AuthenticatorHttpMapper implements MapperInterface<Authenticator, A
|
||||
toProjection(domain: Authenticator): AuthenticatorHttpProjection {
|
||||
return {
|
||||
id: domain.id.toString(),
|
||||
name: domain.props.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ export class AuthenticatorPersistenceMapper implements MapperInterface<Authentic
|
||||
const authenticatorOrError = Authenticator.create(
|
||||
{
|
||||
userUuid,
|
||||
name: projection.name,
|
||||
counter: projection.counter,
|
||||
credentialBackedUp: projection.credentialBackedUp,
|
||||
credentialDeviceType: projection.credentialDeviceType,
|
||||
@@ -43,7 +42,6 @@ export class AuthenticatorPersistenceMapper implements MapperInterface<Authentic
|
||||
const typeorm = new TypeORMAuthenticator()
|
||||
|
||||
typeorm.uuid = domain.id.toString()
|
||||
typeorm.name = domain.props.name
|
||||
typeorm.userUuid = domain.props.userUuid.value
|
||||
typeorm.credentialId = Buffer.from(domain.props.credentialId).toString('base64url')
|
||||
typeorm.credentialPublicKey = Buffer.from(domain.props.credentialPublicKey.buffer)
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.7.5](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.7.4...@standardnotes/event-store@1.7.5) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.7.4](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.7.3...@standardnotes/event-store@1.7.4) (2023-02-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.5",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.10.7](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.10.6...@standardnotes/files-server@1.10.7) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.10.6](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.10.5...@standardnotes/files-server@1.10.6) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.10.6",
|
||||
"version": "1.10.7",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.12.9](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.12.8...@standardnotes/revisions-server@1.12.9) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.12.8](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.12.7...@standardnotes/revisions-server@1.12.8) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.12.8",
|
||||
"version": "1.12.9",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.17.7](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.17.6...@standardnotes/scheduler-server@1.17.7) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.17.6](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.17.5...@standardnotes/scheduler-server@1.17.6) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.17.6",
|
||||
"version": "1.17.7",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.32.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.32.1...@standardnotes/syncing-server@1.32.2) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.32.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.32.0...@standardnotes/syncing-server@1.32.1) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.32.1",
|
||||
"version": "1.32.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.6.8](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.6.7...@standardnotes/websockets-server@1.6.8) (2023-03-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.6.7](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.6.6...@standardnotes/websockets-server@1.6.7) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:18.13.0-alpine
|
||||
FROM node:18.15.0-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.6.7",
|
||||
"version": "1.6.8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user