From 1e69a13a97c4d9022aa96397cce1b349d3cede89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Wed, 28 Dec 2022 11:37:06 +0100 Subject: [PATCH] feat(auth): add authenticators model --- .../1672223738686-add_authenticators.ts | 16 +++++ packages/auth/src/Bootstrap/DataSource.ts | 2 + .../src/Domain/Authenticator/Authenticator.ts | 17 +++++ .../Authenticator/AuthenticatorProps.ts | 8 +++ .../src/Infra/TypeORM/TypeORMAuthenticator.ts | 64 +++++++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 packages/auth/migrations/1672223738686-add_authenticators.ts create mode 100644 packages/auth/src/Domain/Authenticator/Authenticator.ts create mode 100644 packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts create mode 100644 packages/auth/src/Infra/TypeORM/TypeORMAuthenticator.ts diff --git a/packages/auth/migrations/1672223738686-add_authenticators.ts b/packages/auth/migrations/1672223738686-add_authenticators.ts new file mode 100644 index 000000000..43a004879 --- /dev/null +++ b/packages/auth/migrations/1672223738686-add_authenticators.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class addAuthenticators1672223738686 implements MigrationInterface { + name = 'addAuthenticators1672223738686' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + 'CREATE TABLE `authenticators` (`uuid` varchar(36) NOT NULL, `user_uuid` varchar(36) NOT NULL, `credential_id` text NOT NULL, `credential_public_key` blob NOT NULL, `counter` bigint NOT NULL, `credential_device_type` varchar(32) NOT NULL, `credential_backed_up` tinyint NOT NULL, `transports` varchar(255) NULL, `created_at` bigint NOT NULL, `updated_at` bigint NOT NULL, UNIQUE INDEX `credential_id` (`credential_id`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX `credential_id` ON `authenticators`') + await queryRunner.query('DROP TABLE `authenticators`') + } +} diff --git a/packages/auth/src/Bootstrap/DataSource.ts b/packages/auth/src/Bootstrap/DataSource.ts index 6bf9197c1..662af0125 100644 --- a/packages/auth/src/Bootstrap/DataSource.ts +++ b/packages/auth/src/Bootstrap/DataSource.ts @@ -10,6 +10,7 @@ import { SharedSubscriptionInvitation } from '../Domain/SharedSubscription/Share import { OfflineUserSubscription } from '../Domain/Subscription/OfflineUserSubscription' import { UserSubscription } from '../Domain/Subscription/UserSubscription' import { User } from '../Domain/User/User' +import { TypeORMAuthenticator } from '../Infra/TypeORM/TypeORMAuthenticator' import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace' import { Env } from './Env' @@ -58,6 +59,7 @@ export const AppDataSource = new DataSource({ SharedSubscriptionInvitation, SubscriptionSetting, TypeORMSessionTrace, + TypeORMAuthenticator, ], migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'], migrationsRun: true, diff --git a/packages/auth/src/Domain/Authenticator/Authenticator.ts b/packages/auth/src/Domain/Authenticator/Authenticator.ts new file mode 100644 index 000000000..aae19725b --- /dev/null +++ b/packages/auth/src/Domain/Authenticator/Authenticator.ts @@ -0,0 +1,17 @@ +import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core' + +import { AuthenticatorProps } from './AuthenticatorProps' + +export class Authenticator extends Entity { + get id(): UniqueEntityId { + return this._id + } + + private constructor(props: AuthenticatorProps, id?: UniqueEntityId) { + super(props, id) + } + + static create(props: AuthenticatorProps, id?: UniqueEntityId): Result { + return Result.ok(new Authenticator(props, id)) + } +} diff --git a/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts b/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts new file mode 100644 index 000000000..37974ba84 --- /dev/null +++ b/packages/auth/src/Domain/Authenticator/AuthenticatorProps.ts @@ -0,0 +1,8 @@ +export interface AuthenticatorProps { + credentialId: Buffer + credentialPublicKey: Buffer + counter: number + credentialDeviceType: string + credentialBackedUp: boolean + transports?: string[] +} diff --git a/packages/auth/src/Infra/TypeORM/TypeORMAuthenticator.ts b/packages/auth/src/Infra/TypeORM/TypeORMAuthenticator.ts new file mode 100644 index 000000000..4ef8512e7 --- /dev/null +++ b/packages/auth/src/Infra/TypeORM/TypeORMAuthenticator.ts @@ -0,0 +1,64 @@ +import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm' + +@Entity({ name: 'authenticators' }) +export class TypeORMAuthenticator { + @PrimaryGeneratedColumn('uuid') + declare uuid: string + + @Column({ + name: 'user_uuid', + length: 36, + }) + declare userUuid: string + + @Column({ + name: 'credential_id', + type: 'text', + }) + @Index('credential_id', { unique: true }) + declare credentialId: Buffer + + @Column({ + name: 'credential_public_key', + type: 'blob', + }) + declare credentialPublicKey: Buffer + + @Column({ + name: 'counter', + type: 'bigint', + }) + declare counter: number + + @Column({ + name: 'credential_device_type', + type: 'varchar', + length: 32, + }) + declare credentialDeviceType: string + + @Column({ + name: 'credential_backed_up', + }) + declare credentialBackedUp: boolean + + @Column({ + name: 'transports', + type: 'varchar', + length: 255, + nullable: true, + }) + declare transports: string[] + + @Column({ + name: 'created_at', + type: 'bigint', + }) + declare createdAt: number + + @Column({ + name: 'updated_at', + type: 'bigint', + }) + declare updatedAt: number +}