refactor(server): narrow auth types (#16066)

This commit is contained in:
Jason Rasmussen
2025-02-12 15:23:08 -05:00
committed by GitHub
parent 7c821dd205
commit 2d7c333c8c
25 changed files with 265 additions and 239 deletions

View File

@@ -1,12 +1,12 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { ApiKeys, DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { asUuid } from 'src/utils/database';
const columns = ['id', 'name', 'userId', 'createdAt', 'updatedAt', 'permissions'] as const;
@Injectable()
export class ApiKeyRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
@@ -33,29 +33,15 @@ export class ApiKeyRepository {
getKey(hashedToken: string) {
return this.db
.selectFrom('api_keys')
.innerJoinLateral(
(eb) =>
.select((eb) => [
...columns.authApiKey,
jsonObjectFrom(
eb
.selectFrom('users')
.selectAll('users')
.select((eb) =>
eb
.selectFrom('user_metadata')
.whereRef('users.id', '=', 'user_metadata.userId')
.select((eb) => eb.fn('array_agg', [eb.table('user_metadata')]).as('metadata'))
.as('metadata'),
)
.select(columns.authUser)
.whereRef('users.id', '=', 'api_keys.userId')
.where('users.deletedAt', 'is', null)
.as('user'),
(join) => join.onTrue(),
)
.select((eb) => [
'api_keys.id',
'api_keys.key',
'api_keys.userId',
'api_keys.permissions',
eb.fn.toJson('user').as('user'),
.where('users.deletedAt', 'is', null),
).as('user'),
])
.where('api_keys.key', '=', hashedToken)
.executeTakeFirst();
@@ -65,7 +51,7 @@ export class ApiKeyRepository {
getById(userId: string, id: string) {
return this.db
.selectFrom('api_keys')
.select(columns)
.select(columns.apiKey)
.where('id', '=', asUuid(id))
.where('userId', '=', userId)
.executeTakeFirst();
@@ -75,7 +61,7 @@ export class ApiKeyRepository {
getByUserId(userId: string) {
return this.db
.selectFrom('api_keys')
.select(columns)
.select(columns.apiKey)
.where('userId', '=', userId)
.orderBy('createdAt', 'desc')
.execute();

View File

@@ -1,6 +1,8 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, Sessions } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { withUser } from 'src/entities/session.entity';
@@ -25,9 +27,16 @@ export class SessionRepository {
getByToken(token: string) {
return this.db
.selectFrom('sessions')
.innerJoinLateral(withUser, (join) => join.onTrue())
.selectAll('sessions')
.select((eb) => eb.fn.toJson('user').as('user'))
.select((eb) => [
...columns.authSession,
jsonObjectFrom(
eb
.selectFrom('users')
.select(columns.authUser)
.whereRef('users.id', '=', 'sessions.userId')
.where('users.deletedAt', 'is', null),
).as('user'),
])
.where('sessions.token', '=', token)
.executeTakeFirst();
}

View File

@@ -3,6 +3,7 @@ import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import _ from 'lodash';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, SharedLinks } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
@@ -96,7 +97,7 @@ export class SharedLinkRepository {
.executeTakeFirst() as Promise<SharedLinkEntity | undefined>;
}
@GenerateSql({ params: [DummyValue.UUID] })
@GenerateSql({ params: [{ userId: DummyValue.UUID, albumId: DummyValue.UUID }] })
getAll({ userId, albumId }: SharedLinkSearchOptions): Promise<SharedLinkEntity[]> {
return this.db
.selectFrom('shared_links')
@@ -160,39 +161,20 @@ export class SharedLinkRepository {
}
@GenerateSql({ params: [DummyValue.BUFFER] })
async getByKey(key: Buffer): Promise<SharedLinkEntity | undefined> {
async getByKey(key: Buffer) {
return this.db
.selectFrom('shared_links')
.selectAll('shared_links')
.where('shared_links.key', '=', key)
.leftJoin('albums', 'albums.id', 'shared_links.albumId')
.where('albums.deletedAt', 'is', null)
.select((eb) =>
.select((eb) => [
...columns.authSharedLink,
jsonObjectFrom(
eb
.selectFrom('users')
.select([
'users.id',
'users.email',
'users.createdAt',
'users.profileImagePath',
'users.isAdmin',
'users.shouldChangePassword',
'users.deletedAt',
'users.oauthId',
'users.updatedAt',
'users.storageLabel',
'users.name',
'users.quotaSizeInBytes',
'users.quotaUsageInBytes',
'users.status',
'users.profileChangedAt',
])
.whereRef('users.id', '=', 'shared_links.userId'),
eb.selectFrom('users').select(columns.authUser).whereRef('users.id', '=', 'shared_links.userId'),
).as('user'),
)
])
.where((eb) => eb.or([eb('shared_links.type', '=', SharedLinkType.INDIVIDUAL), eb('albums.id', 'is not', null)]))
.executeTakeFirst() as Promise<SharedLinkEntity | undefined>;
.executeTakeFirst();
}
async create(entity: Insertable<SharedLinks> & { assetIds?: string[] }): Promise<SharedLinkEntity> {

View File

@@ -3,7 +3,7 @@ import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, UserMetadata as DbUserMetadata, Users } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { UserMetadata } from 'src/entities/user-metadata.entity';
import { UserMetadata, UserMetadataItem } from 'src/entities/user-metadata.entity';
import { UserEntity, withMetadata } from 'src/entities/user.entity';
import { UserStatus } from 'src/enum';
import { asUuid } from 'src/utils/database';
@@ -64,6 +64,14 @@ export class UserRepository {
.executeTakeFirst() as Promise<UserEntity | undefined>;
}
getMetadata(userId: string) {
return this.db
.selectFrom('user_metadata')
.select(['key', 'value'])
.where('user_metadata.userId', '=', userId)
.execute() as Promise<UserMetadataItem[]>;
}
@GenerateSql()
getAdmin(): Promise<UserEntity | undefined> {
return this.db
@@ -263,7 +271,7 @@ export class UserRepository {
eb
.selectFrom('assets')
.leftJoin('exif', 'exif.assetId', 'assets.id')
.select((eb) => eb.fn.coalesce(eb.fn.sum('exif.fileSizeInByte'), eb.lit(0)).as('usage'))
.select((eb) => eb.fn.coalesce(eb.fn.sum<number>('exif.fileSizeInByte'), eb.lit(0)).as('usage'))
.where('assets.libraryId', 'is', null)
.where('assets.ownerId', '=', eb.ref('users.id')),
updatedAt: new Date(),