From fa9bf0b448acb3f19ab44c4b431ce367dab37b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Wed, 28 Dec 2022 12:40:06 +0100 Subject: [PATCH] feat(auth): add authenticator challenges model --- ...2227471677-add_authenticator_challenges.ts | 16 +++++++++++ packages/auth/src/Bootstrap/DataSource.ts | 2 ++ .../Authenticator/AuthenticatorChallenge.ts | 17 ++++++++++++ .../AuthenticatorChallengeProps.ts | 6 +++++ .../Authenticator/AuthenticatorProps.ts | 3 +++ .../TypeORM/TypeORMAuthenticatorChallenge.ts | 27 +++++++++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 packages/auth/migrations/1672227471677-add_authenticator_challenges.ts create mode 100644 packages/auth/src/Domain/Authenticator/AuthenticatorChallenge.ts create mode 100644 packages/auth/src/Domain/Authenticator/AuthenticatorChallengeProps.ts create mode 100644 packages/auth/src/Infra/TypeORM/TypeORMAuthenticatorChallenge.ts diff --git a/packages/auth/migrations/1672227471677-add_authenticator_challenges.ts b/packages/auth/migrations/1672227471677-add_authenticator_challenges.ts new file mode 100644 index 000000000..5f12ac24c --- /dev/null +++ b/packages/auth/migrations/1672227471677-add_authenticator_challenges.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class addAuthenticatorChallenges1672227471677 implements MigrationInterface { + name = 'addAuthenticatorChallenges1672227471677' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + 'CREATE TABLE `authenticator_challenges` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `challenge` varchar(255) NOT NULL, `created_at` bigint NOT NULL, INDEX `user_uuid_and_challenge` (`user_uuid`, `challenge`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX `user_uuid_and_challenge` ON `authenticator_challenges`') + await queryRunner.query('DROP TABLE `authenticator_challenges`') + } +} diff --git a/packages/auth/src/Bootstrap/DataSource.ts b/packages/auth/src/Bootstrap/DataSource.ts index 662af0125..8b85eeb79 100644 --- a/packages/auth/src/Bootstrap/DataSource.ts +++ b/packages/auth/src/Bootstrap/DataSource.ts @@ -11,6 +11,7 @@ import { OfflineUserSubscription } from '../Domain/Subscription/OfflineUserSubsc import { UserSubscription } from '../Domain/Subscription/UserSubscription' import { User } from '../Domain/User/User' import { TypeORMAuthenticator } from '../Infra/TypeORM/TypeORMAuthenticator' +import { TypeORMAuthenticatorChallenge } from '../Infra/TypeORM/TypeORMAuthenticatorChallenge' import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace' import { Env } from './Env' @@ -60,6 +61,7 @@ export const AppDataSource = new DataSource({ SubscriptionSetting, TypeORMSessionTrace, TypeORMAuthenticator, + TypeORMAuthenticatorChallenge, ], migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'], migrationsRun: true, diff --git a/packages/auth/src/Domain/Authenticator/AuthenticatorChallenge.ts b/packages/auth/src/Domain/Authenticator/AuthenticatorChallenge.ts new file mode 100644 index 000000000..b97303c58 --- /dev/null +++ b/packages/auth/src/Domain/Authenticator/AuthenticatorChallenge.ts @@ -0,0 +1,17 @@ +import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core' + +import { AuthenticatorChallengeProps } from './AuthenticatorChallengeProps' + +export class AuthenticatorChallenge extends Entity { + get id(): UniqueEntityId { + return this._id + } + + private constructor(props: AuthenticatorChallengeProps, id?: UniqueEntityId) { + super(props, id) + } + + static create(props: AuthenticatorChallengeProps, id?: UniqueEntityId): Result { + return Result.ok(new AuthenticatorChallenge(props, id)) + } +} diff --git a/packages/auth/src/Domain/Authenticator/AuthenticatorChallengeProps.ts b/packages/auth/src/Domain/Authenticator/AuthenticatorChallengeProps.ts new file mode 100644 index 000000000..cf42de5d0 --- /dev/null +++ b/packages/auth/src/Domain/Authenticator/AuthenticatorChallengeProps.ts @@ -0,0 +1,6 @@ +import { Uuid } from '@standardnotes/domain-core' + +export interface AuthenticatorChallengeProps { + userUuid: Uuid + challenge: string +} diff --git a/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts b/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts index 37974ba84..9b2a4c2a9 100644 --- a/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts +++ b/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts @@ -1,4 +1,7 @@ +import { Uuid } from '@standardnotes/domain-core' + export interface AuthenticatorProps { + userUuid: Uuid credentialId: Buffer credentialPublicKey: Buffer counter: number diff --git a/packages/auth/src/Infra/TypeORM/TypeORMAuthenticatorChallenge.ts b/packages/auth/src/Infra/TypeORM/TypeORMAuthenticatorChallenge.ts new file mode 100644 index 000000000..e55074097 --- /dev/null +++ b/packages/auth/src/Infra/TypeORM/TypeORMAuthenticatorChallenge.ts @@ -0,0 +1,27 @@ +import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' + +@Entity({ name: 'authenticator_challenges' }) +@Index('user_uuid_and_challenge', ['userUuid', 'challenge']) +export class TypeORMAuthenticatorChallenge { + @PrimaryGeneratedColumn('uuid') + declare uuid: string + + @Column({ + name: 'user_uuid', + length: 36, + }) + declare userUuid: string + + @Column({ + name: 'challenge', + type: 'varchar', + length: 255, + }) + declare challenge: Buffer + + @Column({ + name: 'created_at', + type: 'bigint', + }) + declare createdAt: number +}