mirror of
https://github.com/CaramelFur/Picsur.git
synced 2025-11-14 15:45:49 +01:00
make sure typeorm stays in backend
This commit is contained in:
@@ -5,8 +5,8 @@ import { ImageModule } from './routes/image/imageroute.module';
|
|||||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||||
import Config from './env';
|
import Config from './env';
|
||||||
import { DemoManagerModule } from './managers/demo/demomanager.module';
|
import { DemoManagerModule } from './managers/demo/demomanager.module';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EImageBackend } from './backenddto/image.entity';
|
||||||
import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
import { EUserBackend } from './backenddto/user.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -19,7 +19,7 @@ import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
|||||||
database: Config.database.database,
|
database: Config.database.database,
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
|
|
||||||
entities: [EUser, EImage],
|
entities: [EUserBackend, EImageBackend],
|
||||||
}),
|
}),
|
||||||
ServeStaticModule.forRoot({
|
ServeStaticModule.forRoot({
|
||||||
rootPath: Config.static.frontendRoot,
|
rootPath: Config.static.frontendRoot,
|
||||||
|
|||||||
23
backend/src/backenddto/image.entity.ts
Normal file
23
backend/src/backenddto/image.entity.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import {
|
||||||
|
SupportedMime,
|
||||||
|
SupportedMimes,
|
||||||
|
} from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
|
import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
||||||
|
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class EImageBackend extends EImage {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
override id?: number;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({ unique: true })
|
||||||
|
override hash: string;
|
||||||
|
|
||||||
|
// Binary data
|
||||||
|
@Column({ type: 'bytea', nullable: false, select: false })
|
||||||
|
override data?: Buffer;
|
||||||
|
|
||||||
|
@Column({ enum: SupportedMimes })
|
||||||
|
override mime: SupportedMime;
|
||||||
|
}
|
||||||
20
backend/src/backenddto/user.entity.ts
Normal file
20
backend/src/backenddto/user.entity.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
||||||
|
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
|
// Different data for public and private
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class EUserBackend extends EUser {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
override id?: number;
|
||||||
|
|
||||||
|
@Index()
|
||||||
|
@Column({ unique: true })
|
||||||
|
override username: string;
|
||||||
|
|
||||||
|
@Column({ default: false })
|
||||||
|
override isAdmin: boolean;
|
||||||
|
|
||||||
|
@Column({ select: false })
|
||||||
|
override password?: string;
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { EImageBackend } from '../../backenddto/image.entity';
|
||||||
import { ImageDBService } from './imagedb.service';
|
import { ImageDBService } from './imagedb.service';
|
||||||
import { MimesService } from './mimes.service';
|
import { MimesService } from './mimes.service';
|
||||||
import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([EImage])],
|
imports: [TypeOrmModule.forFeature([EImageBackend])],
|
||||||
providers: [ImageDBService, MimesService],
|
providers: [ImageDBService, MimesService],
|
||||||
exports: [ImageDBService, MimesService],
|
exports: [ImageDBService, MimesService],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,25 +10,25 @@ import {
|
|||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types';
|
||||||
import { SupportedMime } from 'picsur-shared/dist/dto/mimes.dto';
|
import { SupportedMime } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { GetCols } from '../collectionutils';
|
import { GetCols } from '../collectionutils';
|
||||||
import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
|
||||||
import { plainToClass } from 'class-transformer';
|
import { plainToClass } from 'class-transformer';
|
||||||
|
import { EImageBackend } from '../../backenddto/image.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImageDBService {
|
export class ImageDBService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(EImage)
|
@InjectRepository(EImageBackend)
|
||||||
private imageRepository: Repository<EImage>,
|
private imageRepository: Repository<EImageBackend>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async create(
|
public async create(
|
||||||
image: Buffer,
|
image: Buffer,
|
||||||
type: SupportedMime,
|
type: SupportedMime,
|
||||||
): AsyncFailable<EImage> {
|
): AsyncFailable<EImageBackend> {
|
||||||
const hash = this.hash(image);
|
const hash = this.hash(image);
|
||||||
const find = await this.findOne(hash);
|
const find = await this.findOne(hash);
|
||||||
if (HasSuccess(find)) return find;
|
if (HasSuccess(find)) return find;
|
||||||
|
|
||||||
let imageEntity = new EImage();
|
let imageEntity = new EImageBackend();
|
||||||
imageEntity.data = image;
|
imageEntity.data = image;
|
||||||
imageEntity.mime = type;
|
imageEntity.mime = type;
|
||||||
imageEntity.hash = hash;
|
imageEntity.hash = hash;
|
||||||
@@ -40,13 +40,13 @@ export class ImageDBService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strips unwanted data
|
// Strips unwanted data
|
||||||
return plainToClass(EImage, imageEntity);
|
return plainToClass(EImageBackend, imageEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findOne<B extends true | undefined = undefined>(
|
public async findOne<B extends true | undefined = undefined>(
|
||||||
hash: string,
|
hash: string,
|
||||||
getPrivate?: B,
|
getPrivate?: B,
|
||||||
): AsyncFailable<B extends undefined ? EImage : Required<EImage>> {
|
): AsyncFailable<B extends undefined ? EImageBackend : Required<EImageBackend>> {
|
||||||
try {
|
try {
|
||||||
const found = await this.imageRepository.findOne({
|
const found = await this.imageRepository.findOne({
|
||||||
where: { hash },
|
where: { hash },
|
||||||
@@ -54,7 +54,7 @@ export class ImageDBService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!found) return Fail('Image not found');
|
if (!found) return Fail('Image not found');
|
||||||
return found as B extends undefined ? EImage : Required<EImage>;
|
return found as B extends undefined ? EImageBackend : Required<EImageBackend>;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return Fail(e?.message);
|
return Fail(e?.message);
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ export class ImageDBService {
|
|||||||
public async findMany(
|
public async findMany(
|
||||||
startId: number,
|
startId: number,
|
||||||
limit: number,
|
limit: number,
|
||||||
): AsyncFailable<EImage[]> {
|
): AsyncFailable<EImageBackend[]> {
|
||||||
try {
|
try {
|
||||||
const found = await this.imageRepository.find({
|
const found = await this.imageRepository.find({
|
||||||
where: { id: { gte: startId } },
|
where: { id: { gte: startId } },
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUserBackend } from '../../backenddto/user.entity';
|
||||||
import { UsersService } from './userdb.service';
|
import { UsersService } from './userdb.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([EUser])],
|
imports: [TypeOrmModule.forFeature([EUserBackend])],
|
||||||
providers: [UsersService],
|
providers: [UsersService],
|
||||||
exports: [UsersService],
|
exports: [UsersService],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { Injectable, Logger } from '@nestjs/common';
|
|||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { plainToClass } from 'class-transformer';
|
import { plainToClass } from 'class-transformer';
|
||||||
import { validate } from 'class-validator';
|
import { validate } from 'class-validator';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
|
||||||
import {
|
import {
|
||||||
AsyncFailable,
|
AsyncFailable,
|
||||||
Fail,
|
Fail,
|
||||||
@@ -10,6 +9,7 @@ import {
|
|||||||
HasSuccess,
|
HasSuccess,
|
||||||
} from 'picsur-shared/dist/types';
|
} from 'picsur-shared/dist/types';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
import { EUserBackend } from '../../backenddto/user.entity';
|
||||||
import { GetCols } from '../collectionutils';
|
import { GetCols } from '../collectionutils';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -17,17 +17,17 @@ export class UsersService {
|
|||||||
private readonly logger = new Logger('UsersService');
|
private readonly logger = new Logger('UsersService');
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(EUser)
|
@InjectRepository(EUserBackend)
|
||||||
private usersRepository: Repository<EUser>,
|
private usersRepository: Repository<EUserBackend>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async create(
|
public async create(
|
||||||
username: string,
|
username: string,
|
||||||
hashedPassword: string,
|
hashedPassword: string,
|
||||||
): AsyncFailable<EUser> {
|
): AsyncFailable<EUserBackend> {
|
||||||
if (await this.exists(username)) return Fail('User already exists');
|
if (await this.exists(username)) return Fail('User already exists');
|
||||||
|
|
||||||
let user = new EUser();
|
let user = new EUserBackend();
|
||||||
user.username = username;
|
user.username = username;
|
||||||
user.password = hashedPassword;
|
user.password = hashedPassword;
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@ export class UsersService {
|
|||||||
return Fail(e?.message);
|
return Fail(e?.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return plainToClass(EUser, user); // Strips unwanted data
|
return plainToClass(EUserBackend, user); // Strips unwanted data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns user object without id
|
// Returns user object without id
|
||||||
public async delete(user: string | EUser): AsyncFailable<EUser> {
|
public async delete(user: string | EUserBackend): AsyncFailable<EUserBackend> {
|
||||||
const userToModify = await this.resolve(user);
|
const userToModify = await this.resolve(user);
|
||||||
if (HasFailed(userToModify)) return userToModify;
|
if (HasFailed(userToModify)) return userToModify;
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export class UsersService {
|
|||||||
public async findOne<B extends true | undefined = undefined>(
|
public async findOne<B extends true | undefined = undefined>(
|
||||||
username: string,
|
username: string,
|
||||||
getPrivate?: B,
|
getPrivate?: B,
|
||||||
): AsyncFailable<B extends undefined ? EUser : Required<EUser>> {
|
): AsyncFailable<B extends undefined ? EUserBackend : Required<EUserBackend>> {
|
||||||
try {
|
try {
|
||||||
const found = await this.usersRepository.findOne({
|
const found = await this.usersRepository.findOne({
|
||||||
where: { username },
|
where: { username },
|
||||||
@@ -63,13 +63,13 @@ export class UsersService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!found) return Fail('User not found');
|
if (!found) return Fail('User not found');
|
||||||
return found as B extends undefined ? EUser : Required<EUser>;
|
return found as B extends undefined ? EUserBackend : Required<EUserBackend>;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return Fail(e?.message);
|
return Fail(e?.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findAll(): AsyncFailable<EUser[]> {
|
public async findAll(): AsyncFailable<EUserBackend[]> {
|
||||||
try {
|
try {
|
||||||
return await this.usersRepository.find();
|
return await this.usersRepository.find();
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -82,7 +82,7 @@ export class UsersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async modifyAdmin(
|
public async modifyAdmin(
|
||||||
user: string | EUser,
|
user: string | EUserBackend,
|
||||||
admin: boolean,
|
admin: boolean,
|
||||||
): AsyncFailable<true> {
|
): AsyncFailable<true> {
|
||||||
const userToModify = await this.resolve(user);
|
const userToModify = await this.resolve(user);
|
||||||
@@ -94,11 +94,11 @@ export class UsersService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async resolve(user: string | EUser): AsyncFailable<EUser> {
|
private async resolve(user: string | EUserBackend): AsyncFailable<EUserBackend> {
|
||||||
if (typeof user === 'string') {
|
if (typeof user === 'string') {
|
||||||
return await this.findOne(user);
|
return await this.findOne(user);
|
||||||
} else {
|
} else {
|
||||||
user = plainToClass(EUser, user);
|
user = plainToClass(EUserBackend, user);
|
||||||
const errors = await validate(user, { forbidUnknownValues: true });
|
const errors = await validate(user, { forbidUnknownValues: true });
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
this.logger.warn(errors);
|
this.logger.warn(errors);
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { isHash } from 'class-validator';
|
|
||||||
import { fileTypeFromBuffer, FileTypeResult } from 'file-type';
|
import { fileTypeFromBuffer, FileTypeResult } from 'file-type';
|
||||||
import { FullMime } from 'picsur-shared/dist/dto/mimes.dto';
|
import { FullMime } from 'picsur-shared/dist/dto/mimes.dto';
|
||||||
import { EImage } from 'picsur-shared/dist/entities/image.entity';
|
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
||||||
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
|
import { EImageBackend } from '../../backenddto/image.entity';
|
||||||
import { ImageDBService } from '../../collections/imagedb/imagedb.service';
|
import { ImageDBService } from '../../collections/imagedb/imagedb.service';
|
||||||
import { MimesService } from '../../collections/imagedb/mimes.service';
|
import { MimesService } from '../../collections/imagedb/mimes.service';
|
||||||
|
|
||||||
@@ -14,16 +13,16 @@ export class ImageManagerService {
|
|||||||
private readonly mimesService: MimesService,
|
private readonly mimesService: MimesService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async retrieveInfo(hash: string): AsyncFailable<EImage> {
|
public async retrieveInfo(hash: string): AsyncFailable<EImageBackend> {
|
||||||
return await this.imagesService.findOne(hash);
|
return await this.imagesService.findOne(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image data buffer is not included by default, this also returns that buffer
|
// Image data buffer is not included by default, this also returns that buffer
|
||||||
public async retrieveComplete(hash: string): AsyncFailable<Required<EImage>> {
|
public async retrieveComplete(hash: string): AsyncFailable<Required<EImageBackend>> {
|
||||||
return await this.imagesService.findOne(hash, true);
|
return await this.imagesService.findOne(hash, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async upload(image: Buffer): AsyncFailable<EImage> {
|
public async upload(image: Buffer): AsyncFailable<EImageBackend> {
|
||||||
const fullMime = await this.getFullMimeFromBuffer(image);
|
const fullMime = await this.getFullMimeFromBuffer(image);
|
||||||
if (HasFailed(fullMime)) return fullMime;
|
if (HasFailed(fullMime)) return fullMime;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { plainToClass } from 'class-transformer';
|
import { plainToClass } from 'class-transformer';
|
||||||
import { validate } from 'class-validator';
|
import { validate } from 'class-validator';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUserBackend } from '../../../backenddto/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdminGuard implements CanActivate {
|
export class AdminGuard implements CanActivate {
|
||||||
@@ -15,7 +15,7 @@ export class AdminGuard implements CanActivate {
|
|||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
|
|
||||||
const user = plainToClass(EUser, request.user);
|
const user = plainToClass(EUserBackend, request.user);
|
||||||
const errors = await validate(user, {forbidUnknownValues: true});
|
const errors = await validate(user, {forbidUnknownValues: true});
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
this.logger.warn(errors);
|
this.logger.warn(errors);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import * as bcrypt from 'bcrypt';
|
|||||||
import { instanceToPlain, plainToClass } from 'class-transformer';
|
import { instanceToPlain, plainToClass } from 'class-transformer';
|
||||||
import { validate } from 'class-validator';
|
import { validate } from 'class-validator';
|
||||||
import { JwtDataDto } from 'picsur-shared/dist/dto/auth.dto';
|
import { JwtDataDto } from 'picsur-shared/dist/dto/auth.dto';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
|
||||||
import { AsyncFailable, HasFailed, Fail } from 'picsur-shared/dist/types';
|
import { AsyncFailable, HasFailed, Fail } from 'picsur-shared/dist/types';
|
||||||
|
import { EUserBackend } from '../../../backenddto/user.entity';
|
||||||
import { UsersService } from '../../../collections/userdb/userdb.service';
|
import { UsersService } from '../../../collections/userdb/userdb.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -17,20 +17,20 @@ export class AuthService {
|
|||||||
private jwtService: JwtService,
|
private jwtService: JwtService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async createUser(username: string, password: string): AsyncFailable<EUser> {
|
async createUser(username: string, password: string): AsyncFailable<EUserBackend> {
|
||||||
const hashedPassword = await bcrypt.hash(password, 12);
|
const hashedPassword = await bcrypt.hash(password, 12);
|
||||||
return this.usersService.create(username, hashedPassword);
|
return this.usersService.create(username, hashedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteUser(user: string | EUser): AsyncFailable<EUser> {
|
async deleteUser(user: string | EUserBackend): AsyncFailable<EUserBackend> {
|
||||||
return this.usersService.delete(user);
|
return this.usersService.delete(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
async listUsers(): AsyncFailable<EUser[]> {
|
async listUsers(): AsyncFailable<EUserBackend[]> {
|
||||||
return this.usersService.findAll();
|
return this.usersService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticate(username: string, password: string): AsyncFailable<EUser> {
|
async authenticate(username: string, password: string): AsyncFailable<EUserBackend> {
|
||||||
const user = await this.usersService.findOne(username, true);
|
const user = await this.usersService.findOne(username, true);
|
||||||
if (HasFailed(user)) return user;
|
if (HasFailed(user)) return user;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export class AuthService {
|
|||||||
return await this.usersService.findOne(username);
|
return await this.usersService.findOne(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
async createToken(user: EUser): Promise<string> {
|
async createToken(user: EUserBackend): Promise<string> {
|
||||||
const jwtData: JwtDataDto = plainToClass(JwtDataDto, {
|
const jwtData: JwtDataDto = plainToClass(JwtDataDto, {
|
||||||
user,
|
user,
|
||||||
});
|
});
|
||||||
@@ -54,11 +54,11 @@ export class AuthService {
|
|||||||
return this.jwtService.signAsync(instanceToPlain(jwtData));
|
return this.jwtService.signAsync(instanceToPlain(jwtData));
|
||||||
}
|
}
|
||||||
|
|
||||||
async makeAdmin(user: string | EUser): AsyncFailable<true> {
|
async makeAdmin(user: string | EUserBackend): AsyncFailable<true> {
|
||||||
return this.usersService.modifyAdmin(user, true);
|
return this.usersService.modifyAdmin(user, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async revokeAdmin(user: string | EUser): AsyncFailable<true> {
|
async revokeAdmin(user: string | EUserBackend): AsyncFailable<true> {
|
||||||
return this.usersService.modifyAdmin(user, false);
|
return this.usersService.modifyAdmin(user, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { FastifyRequest } from 'fastify';
|
import { FastifyRequest } from 'fastify';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUserBackend } from '../../../backenddto/user.entity';
|
||||||
|
|
||||||
export default interface AuthFasityRequest extends FastifyRequest {
|
export default interface AuthFasityRequest extends FastifyRequest {
|
||||||
user: EUser;
|
user: EUserBackend;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { validate } from 'class-validator';
|
|||||||
import { plainToClass } from 'class-transformer';
|
import { plainToClass } from 'class-transformer';
|
||||||
import Config from '../../../env';
|
import Config from '../../../env';
|
||||||
import { JwtDataDto } from 'picsur-shared/dist/dto/auth.dto';
|
import { JwtDataDto } from 'picsur-shared/dist/dto/auth.dto';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUserBackend } from '../../../backenddto/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||||
@@ -19,7 +19,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(payload: any): Promise<EUser> {
|
async validate(payload: any): Promise<EUserBackend> {
|
||||||
const jwt = plainToClass(JwtDataDto, payload);
|
const jwt = plainToClass(JwtDataDto, payload);
|
||||||
|
|
||||||
const errors = await validate(jwt, {
|
const errors = await validate(jwt, {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
|||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
|
||||||
import { EUser } from 'picsur-shared/dist/entities/user.entity';
|
import { EUserBackend } from '../../../backenddto/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LocalStrategy extends PassportStrategy(Strategy, 'local') {
|
export class LocalStrategy extends PassportStrategy(Strategy, 'local') {
|
||||||
@@ -11,7 +11,7 @@ export class LocalStrategy extends PassportStrategy(Strategy, 'local') {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate(username: string, password: string): AsyncFailable<EUser> {
|
async validate(username: string, password: string): AsyncFailable<EUserBackend> {
|
||||||
const user = await this.authService.authenticate(username, password);
|
const user = await this.authService.authenticate(username, password);
|
||||||
if (HasFailed(user)) {
|
if (HasFailed(user)) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.13.2",
|
"class-validator": "^0.13.2",
|
||||||
"tsc-watch": "^4.6.0",
|
"tsc-watch": "^4.6.0"
|
||||||
"typeorm": "^0.2.44"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "^17.0.21",
|
||||||
|
|||||||
@@ -5,27 +5,27 @@ import {
|
|||||||
IsHash,
|
IsHash,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
//import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
import { SupportedMime, SupportedMimes } from '../dto/mimes.dto';
|
import { SupportedMime, SupportedMimes } from '../dto/mimes.dto';
|
||||||
|
|
||||||
@Entity()
|
//@Entity()
|
||||||
export class EImage {
|
export class EImage {
|
||||||
@PrimaryGeneratedColumn()
|
// @PrimaryGeneratedColumn()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
||||||
@Index()
|
// @Index()
|
||||||
@Column({ unique: true })
|
// @Column({ unique: true })
|
||||||
@IsHash('sha256')
|
@IsHash('sha256')
|
||||||
hash: string;
|
hash: string;
|
||||||
|
|
||||||
// Binary data
|
// Binary data
|
||||||
@Column({ type: 'bytea', nullable: false, select: false })
|
// @Column({ type: 'bytea', nullable: false, select: false })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Exclude()
|
@Exclude()
|
||||||
data?: Buffer;
|
data?: Buffer;
|
||||||
|
|
||||||
@Column({ enum: SupportedMimes })
|
// @Column({ enum: SupportedMimes })
|
||||||
@IsEnum(SupportedMimes)
|
@IsEnum(SupportedMimes)
|
||||||
@IsDefined()
|
@IsDefined()
|
||||||
mime: SupportedMime;
|
mime: SupportedMime;
|
||||||
|
|||||||
@@ -5,26 +5,26 @@ import {
|
|||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
// import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
// Different data for public and private
|
// Different data for public and private
|
||||||
|
|
||||||
@Entity()
|
// @Entity()
|
||||||
export class EUser {
|
export class EUser {
|
||||||
@PrimaryGeneratedColumn()
|
// @PrimaryGeneratedColumn()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
||||||
@Index()
|
// @Index()
|
||||||
@Column({ unique: true })
|
// @Column({ unique: true })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
username: string;
|
username: string;
|
||||||
|
|
||||||
@Column({ default: false })
|
// @Column({ default: false })
|
||||||
@IsDefined()
|
@IsDefined()
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
|
|
||||||
@Column({ select: false })
|
// @Column({ select: false })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Exclude()
|
@Exclude()
|
||||||
password?: string;
|
password?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user