feat(auth): add cache entries model (#576)

This commit is contained in:
Karol Sójko 2023-05-01 09:49:27 +02:00 committed by GitHub
parent a29ac8e68f
commit 56c922e715
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 0 deletions

View file

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class cacheEntries1682926032072 implements MigrationInterface {
name = 'cacheEntries1682926032072'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'CREATE TABLE `cache_entries` (`uuid` varchar(36) NOT NULL, `key` text NOT NULL, `value` text NOT NULL, `expires_at` datetime NULL, PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP TABLE `cache_entries`')
}
}

View file

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class cacheEntries1682925969528 implements MigrationInterface {
name = 'cacheEntries1682925969528'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'CREATE TABLE "cache_entries" ("uuid" varchar PRIMARY KEY NOT NULL, "key" text NOT NULL, "value" text NOT NULL, "expires_at" datetime)',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP TABLE "cache_entries"')
}
}

View file

@ -14,6 +14,7 @@ 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 { TypeORMCacheEntry } from '../Infra/TypeORM/TypeORMCacheEntry'
import { TypeORMEmergencyAccessInvitation } from '../Infra/TypeORM/TypeORMEmergencyAccessInvitation'
import { TypeORMSessionTrace } from '../Infra/TypeORM/TypeORMSessionTrace'
import { Env } from './Env'
@ -68,6 +69,7 @@ const commonDataSourceOptions = {
TypeORMAuthenticator,
TypeORMAuthenticatorChallenge,
TypeORMEmergencyAccessInvitation,
TypeORMCacheEntry,
],
migrations: [`dist/migrations/${isConfiguredForMySQL ? 'mysql' : 'sqlite'}/*.js`],
migrationsRun: true,

View file

@ -0,0 +1,17 @@
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { CacheEntryProps } from './CacheEntryProps'
export class CacheEntry extends Entity<CacheEntryProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: CacheEntryProps, id?: UniqueEntityId) {
super(props, id)
}
static create(props: CacheEntryProps, id?: UniqueEntityId): Result<CacheEntry> {
return Result.ok<CacheEntry>(new CacheEntry(props, id))
}
}

View file

@ -0,0 +1,5 @@
export interface CacheEntryProps {
key: string
value: string
expiresAt: Date | null
}

View file

@ -0,0 +1,6 @@
import { CacheEntry } from './CacheEntry'
export interface CacheEntryRepositoryInterface {
save(cacheEntry: CacheEntry): Promise<CacheEntry>
findOneByKey(key: string): Promise<CacheEntry | null>
}

View file

@ -0,0 +1,26 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
@Entity({ name: 'cache_entries' })
export class TypeORMCacheEntry {
@PrimaryGeneratedColumn('uuid')
declare uuid: string
@Column({
name: 'key',
type: 'text',
})
declare key: string
@Column({
name: 'value',
type: 'text',
})
declare value: string
@Column({
name: 'expires_at',
type: 'datetime',
nullable: true,
})
declare expiresAt: Date | null
}

View file

@ -0,0 +1,33 @@
import { MapperInterface, UniqueEntityId } from '@standardnotes/domain-core'
import { CacheEntry } from '../Domain/Cache/CacheEntry'
import { TypeORMCacheEntry } from '../Infra/TypeORM/TypeORMCacheEntry'
export class CacheEntryPersistenceMapper implements MapperInterface<CacheEntry, TypeORMCacheEntry> {
toDomain(projection: TypeORMCacheEntry): CacheEntry {
const cacheEntryOrError = CacheEntry.create(
{
key: projection.key,
value: projection.value,
expiresAt: projection.expiresAt,
},
new UniqueEntityId(projection.uuid),
)
if (cacheEntryOrError.isFailed()) {
throw new Error(`CacheEntryPersistenceMapper.toDomain: ${cacheEntryOrError.getError()}`)
}
return cacheEntryOrError.getValue()
}
toProjection(domain: CacheEntry): TypeORMCacheEntry {
const typeorm = new TypeORMCacheEntry()
typeorm.uuid = domain.id.toString()
typeorm.key = domain.props.key
typeorm.value = domain.props.value
typeorm.expiresAt = domain.props.expiresAt
return typeorm
}
}