Compare commits
2 Commits
18a5999334
...
ff649ebdbf
| Author | SHA1 | Date | |
|---|---|---|---|
|
ff649ebdbf
|
|||
|
6f0f209e00
|
@@ -1,14 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Delete,
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
HttpCode,
|
HttpCode,
|
||||||
HttpStatus,
|
HttpStatus,
|
||||||
Patch,
|
Patch,
|
||||||
Post,
|
Post,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto";
|
import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto";
|
||||||
import { AuthService } from "apps/backend/src/app/auth/auth.service";
|
import { AuthService } from "apps/backend/src/app/auth/auth.service";
|
||||||
@@ -16,52 +16,50 @@ import { UserGuard } from "./auth.guard";
|
|||||||
|
|
||||||
@Controller("auth")
|
@Controller("auth")
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private readonly authService: AuthService) {}
|
constructor(private readonly authService: AuthService) { }
|
||||||
|
|
||||||
//TODO Initial account validation for admin privileges
|
//TODO Initial account validation for admin privileges
|
||||||
//POST signup
|
//POST signup
|
||||||
@HttpCode(HttpStatus.CREATED)
|
@HttpCode(HttpStatus.CREATED)
|
||||||
@Post("signup")
|
@Post("signup")
|
||||||
async signUp(@Body() dto: SignUpDto) {
|
async signUp(@Body() dto: SignUpDto) {
|
||||||
console.log(dto);
|
return this.authService.doRegister(dto);
|
||||||
return this.authService.doRegister(dto);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//POST signin
|
//POST signin
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@Post("signin")
|
@Post("signin")
|
||||||
async signIn(@Body() dto: SignInDto) {
|
async signIn(@Body() dto: SignInDto) {
|
||||||
console.log(dto);
|
return this.authService.doLogin(dto);
|
||||||
return this.authService.doLogin(dto);
|
}
|
||||||
}
|
//GET me -- Get current user data via jwt
|
||||||
//GET me -- Get current user data via jwt
|
@HttpCode(HttpStatus.OK)
|
||||||
@HttpCode(HttpStatus.OK)
|
@Get("me")
|
||||||
@Get("me")
|
@UseGuards(UserGuard)
|
||||||
@UseGuards(UserGuard)
|
async getMe(@Body() body: object) {
|
||||||
async getMe(@Body() body: object) {
|
// @ts-ignore
|
||||||
// @ts-ignore
|
const targetId = body.sourceUserId;
|
||||||
const targetId = body.sourceUserId;
|
const userData = await this.authService.fetchUserById(targetId);
|
||||||
const userData = await this.authService.fetchUserById(targetId);
|
if (!userData) {
|
||||||
if (!userData) {
|
throw new UnauthorizedException();
|
||||||
throw new UnauthorizedException();
|
}
|
||||||
}
|
return userData;
|
||||||
return userData;
|
}
|
||||||
}
|
//DELETE me
|
||||||
//DELETE me
|
@HttpCode(HttpStatus.FOUND)
|
||||||
@HttpCode(HttpStatus.FOUND)
|
@Delete("me")
|
||||||
@Delete("me")
|
@UseGuards(UserGuard)
|
||||||
@UseGuards(UserGuard)
|
async deleteMe(@Body() body: object) {
|
||||||
async deleteMe(@Body() body: object) {
|
// @ts-ignore
|
||||||
// @ts-ignore
|
const targetId = body.sourceUserId;
|
||||||
const targetId = body.sourceUserId;
|
try {
|
||||||
try {
|
await this.authService.deleteUser(targetId);
|
||||||
await this.authService.deleteUser(targetId);
|
} catch (err) {
|
||||||
} catch (err) {
|
throw new UnauthorizedException();
|
||||||
throw new UnauthorizedException();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//PATCH me
|
//PATCH me
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@Patch("me")
|
@Patch("me")
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ export class SignUpDto {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsStrongPassword({
|
@IsStrongPassword({
|
||||||
minLength: 6,
|
minLength: 6,
|
||||||
minSymbols: 1,
|
|
||||||
})
|
})
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
@@ -46,7 +45,6 @@ export class SignInDto {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsStrongPassword({
|
@IsStrongPassword({
|
||||||
minLength: 6,
|
minLength: 6,
|
||||||
minSymbols: 1,
|
|
||||||
})
|
})
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
Injectable,
|
Injectable,
|
||||||
OnModuleInit,
|
OnModuleInit,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto";
|
import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto";
|
||||||
import { CredentialsService } from "apps/backend/src/app/credentials/credentials.service";
|
import { CredentialsService } from "apps/backend/src/app/credentials/credentials.service";
|
||||||
@@ -11,103 +11,102 @@ import { eq } from "drizzle-orm";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService implements OnModuleInit {
|
export class AuthService implements OnModuleInit {
|
||||||
constructor(
|
constructor(
|
||||||
private db: DbService,
|
private db: DbService,
|
||||||
private credentials: CredentialsService,
|
private credentials: CredentialsService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
//TODO Initial account validation for admin privileges
|
//TODO Initial account validation for admin privileges
|
||||||
async doRegister(data: SignUpDto) {
|
async doRegister(data: SignUpDto) {
|
||||||
console.log(data);
|
const existingUser = await this.db
|
||||||
const existingUser = await this.db
|
.use()
|
||||||
.use()
|
.select()
|
||||||
.select()
|
.from(UsersTable)
|
||||||
.from(UsersTable)
|
.where(eq(UsersTable.email, data.email))
|
||||||
.where(eq(UsersTable.email, data.email))
|
.prepare("userByEmail")
|
||||||
.prepare("userByEmail")
|
.execute();
|
||||||
.execute();
|
if (existingUser.length !== 0)
|
||||||
if (existingUser.length !== 0)
|
throw new UnauthorizedException("Already exist");
|
||||||
throw new UnauthorizedException("Already exist");
|
const query = await this.db
|
||||||
const query = await this.db
|
.use()
|
||||||
.use()
|
.insert(UsersTable)
|
||||||
.insert(UsersTable)
|
.values({
|
||||||
.values({
|
//firstName: data.firstName,
|
||||||
//firstName: data.firstName,
|
//lastName: data.lastName,
|
||||||
//lastName: data.lastName,
|
email: data.email,
|
||||||
email: data.email,
|
hash: await this.credentials.hash(data.password),
|
||||||
hash: await this.credentials.hash(data.password),
|
})
|
||||||
})
|
.returning()
|
||||||
.returning()
|
.prepare("insertUser")
|
||||||
.prepare("insertUser")
|
.execute()
|
||||||
.execute()
|
.catch((err) => {
|
||||||
.catch((err) => {
|
console.error(err);
|
||||||
console.error(err);
|
throw new UnauthorizedException(
|
||||||
throw new UnauthorizedException(
|
"Error occurred while inserting user",
|
||||||
"Error occurred while inserting user",
|
err,
|
||||||
err,
|
);
|
||||||
);
|
});
|
||||||
});
|
return {
|
||||||
return {
|
message: "User created, check your email for validation.",
|
||||||
message: "User created, check your email for validation.",
|
token: await this.credentials.signAuthToken({ sub: query[0].uuid }),
|
||||||
token: await this.credentials.signAuthToken({ sub: query[0].uuid }),
|
};
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async doLogin(data: SignInDto) {
|
async doLogin(data: SignInDto) {
|
||||||
const user = await this.db
|
const user = await this.db
|
||||||
.use()
|
.use()
|
||||||
.select()
|
.select()
|
||||||
.from(UsersTable)
|
.from(UsersTable)
|
||||||
.where(eq(UsersTable.email, data.email))
|
.where(eq(UsersTable.email, data.email))
|
||||||
.prepare("userByEmail")
|
.prepare("userByEmail")
|
||||||
.execute();
|
.execute();
|
||||||
if (user.length !== 1)
|
if (user.length !== 1)
|
||||||
throw new UnauthorizedException("Invalid credentials");
|
throw new UnauthorizedException("Invalid credentials");
|
||||||
const passwordMatch = await this.credentials.check(
|
const passwordMatch = await this.credentials.check(
|
||||||
data.password,
|
data.password,
|
||||||
user[0].hash,
|
user[0].hash,
|
||||||
);
|
);
|
||||||
if (!passwordMatch) throw new UnauthorizedException("Invalid credentials");
|
if (!passwordMatch) throw new UnauthorizedException("Invalid credentials");
|
||||||
const token = await this.credentials.signAuthToken({ sub: user[0].uuid });
|
const token = await this.credentials.signAuthToken({ sub: user[0].uuid });
|
||||||
return {
|
return {
|
||||||
message: "Login successful",
|
message: "Login successful",
|
||||||
token: token,
|
token: token,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchUserById(userId: string) {
|
async fetchUserById(userId: string) {
|
||||||
const user = await this.db
|
const user = await this.db
|
||||||
.use()
|
.use()
|
||||||
.select()
|
.select()
|
||||||
.from(UsersTable)
|
.from(UsersTable)
|
||||||
.where(eq(UsersTable.uuid, userId))
|
.where(eq(UsersTable.uuid, userId))
|
||||||
.prepare("userById")
|
.prepare("userById")
|
||||||
.execute();
|
.execute();
|
||||||
if (user.length !== 1) {
|
if (user.length !== 1) {
|
||||||
throw new UnauthorizedException("User not found");
|
throw new UnauthorizedException("User not found");
|
||||||
}
|
}
|
||||||
delete user[0].hash;
|
delete user[0].hash;
|
||||||
//delete user[0].emailCode;
|
//delete user[0].emailCode;
|
||||||
return user[0];
|
return user[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchUsers() {
|
async fetchUsers() {
|
||||||
//TODO Pagination
|
//TODO Pagination
|
||||||
const usersInDb = await this.db.use().select().from(UsersTable);
|
const usersInDb = await this.db.use().select().from(UsersTable);
|
||||||
const result = {
|
const result = {
|
||||||
total: usersInDb.length,
|
total: usersInDb.length,
|
||||||
users: usersInDb.map((user) => {
|
users: usersInDb.map((user) => {
|
||||||
delete user.hash;
|
delete user.hash;
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
console.log(result);
|
console.log(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
async updateUser(targetId: string, userData: IUserUpdateData) {
|
async updateUser(targetId: string, userData: IUserUpdateData) {
|
||||||
const validationResult = UserUpdateSchema.safeParse(userData);
|
const validationResult = UserUpdateSchema.safeParse(userData);
|
||||||
if (!validationResult.success) {
|
if (!validationResult.success) {
|
||||||
@@ -133,26 +132,26 @@ export class AuthService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async deleteUser(targetId: string) {
|
async deleteUser(targetId: string) {
|
||||||
await this.db
|
await this.db
|
||||||
.use()
|
.use()
|
||||||
.delete(UsersTable)
|
.delete(UsersTable)
|
||||||
.where(eq(UsersTable.uuid, targetId))
|
.where(eq(UsersTable.uuid, targetId))
|
||||||
.prepare("deleteUserById")
|
.prepare("deleteUserById")
|
||||||
.execute()
|
.execute()
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
throw new UnauthorizedException(
|
throw new UnauthorizedException(
|
||||||
"Error occurred while deleting user",
|
"Error occurred while deleting user",
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.fetchUsers();
|
this.fetchUsers();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,52 +6,51 @@ import { JWTPayload, generateSecret } from "jose";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CredentialsService {
|
export class CredentialsService {
|
||||||
constructor(private readonly configService: ConfigService) {}
|
constructor(private readonly configService: ConfigService) { }
|
||||||
|
|
||||||
async hash(plaintextPassword: string) {
|
async hash(plaintextPassword: string) {
|
||||||
console.log(plaintextPassword);
|
if (plaintextPassword.length < 6)
|
||||||
if (plaintextPassword.length < 6)
|
throw new BadRequestException("Password is not strong enough !");
|
||||||
throw new BadRequestException("Password is not strong enough !");
|
return argon.hash(plaintextPassword, {
|
||||||
return argon.hash(plaintextPassword, {
|
secret: Buffer.from(this.configService.get("APP_HASH_SECRET")),
|
||||||
secret: Buffer.from(this.configService.get("APP_HASH_SECRET")),
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async check(plaintextPassword: string, hashedPassword: string) {
|
async check(plaintextPassword: string, hashedPassword: string) {
|
||||||
return argon.verify(hashedPassword, plaintextPassword, {
|
return argon.verify(hashedPassword, plaintextPassword, {
|
||||||
secret: Buffer.from(this.configService.get("APP_HASH_SECRET")),
|
secret: Buffer.from(this.configService.get("APP_HASH_SECRET")),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async verifyAuthToken(token: string) {
|
async verifyAuthToken(token: string) {
|
||||||
try {
|
try {
|
||||||
const result = await jose.jwtVerify(
|
const result = await jose.jwtVerify(
|
||||||
token,
|
token,
|
||||||
Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")),
|
Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")),
|
||||||
{
|
{
|
||||||
audience: "auth:user",
|
audience: "auth:user",
|
||||||
issuer: "FabLab",
|
issuer: "FabLab",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
console.log(result);
|
console.log(result);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
throw new BadRequestException("Invalid token");
|
throw new BadRequestException("Invalid token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async signAuthToken(payload: JWTPayload) {
|
async signAuthToken(payload: JWTPayload) {
|
||||||
console.log(this.configService.get("APP_TOKEN_SECRET"));
|
console.log(this.configService.get("APP_TOKEN_SECRET"));
|
||||||
const token = new jose.SignJWT(payload)
|
const token = new jose.SignJWT(payload)
|
||||||
.setProtectedHeader({ alg: "HS512", enc: "A128CBC-HS512" })
|
.setProtectedHeader({ alg: "HS512", enc: "A128CBC-HS512" })
|
||||||
.setIssuedAt()
|
.setIssuedAt()
|
||||||
.setExpirationTime("5 day")
|
.setExpirationTime("5 day")
|
||||||
.setIssuer("FabLab")
|
.setIssuer("FabLab")
|
||||||
.setAudience("auth:user");
|
.setAudience("auth:user");
|
||||||
console.log(token);
|
console.log(token);
|
||||||
return await token.sign(
|
return await token.sign(
|
||||||
Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")),
|
Uint8Array.from(this.configService.get("APP_TOKEN_SECRET")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
import { IncomingMessage } from "node:http";
|
import { IncomingMessage } from "node:http";
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
DefaultValuePipe,
|
DefaultValuePipe,
|
||||||
Delete,
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
HttpCode,
|
HttpCode,
|
||||||
HttpStatus,
|
HttpStatus,
|
||||||
Param,
|
Param,
|
||||||
ParseIntPipe,
|
ParseIntPipe,
|
||||||
ParseUUIDPipe,
|
ParseUUIDPipe,
|
||||||
Post,
|
Post,
|
||||||
Query,
|
Query,
|
||||||
Req,
|
Req,
|
||||||
Request,
|
Request,
|
||||||
Res,
|
Res,
|
||||||
Response,
|
Response,
|
||||||
StreamableFile,
|
StreamableFile,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { CreateFileTypeDto } from "apps/backend/src/app/files/files.dto";
|
import { CreateFileTypeDto } from "apps/backend/src/app/files/files.dto";
|
||||||
import { AdminGuard, InsertAdminState } from "../auth/auth.guard";
|
import { AdminGuard, InsertAdminState } from "../auth/auth.guard";
|
||||||
@@ -26,130 +26,132 @@ import { FilesService } from "./files.service";
|
|||||||
|
|
||||||
@Controller("files")
|
@Controller("files")
|
||||||
export class FilesController {
|
export class FilesController {
|
||||||
constructor(private readonly filesService: FilesService) {}
|
constructor(private readonly filesService: FilesService) { }
|
||||||
|
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@UseGuards(InsertAdminState)
|
@UseGuards(InsertAdminState)
|
||||||
@Post("new")
|
@Post("new")
|
||||||
async saveFile(@Req() req: IncomingMessage, @Res() res: Response) {
|
async saveFile(@Req() req: IncomingMessage, @Res() res: Response) {
|
||||||
let fileBuffer: Buffer = Buffer.from([]);
|
let fileBuffer: Buffer = Buffer.from([]);
|
||||||
req.on("data", (chunk: Buffer) => {
|
req.on("data", (chunk: Buffer) => {
|
||||||
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on("end", async () => {
|
req.on("end", async () => {
|
||||||
try {
|
try {
|
||||||
console.log(fileBuffer);
|
console.log(fileBuffer);
|
||||||
const _fileName = req.headers["file_name"] as string;
|
const _fileName = req.headers["file_name"] as string;
|
||||||
const _groupId = req.headers["group_id"] as string;
|
const _groupId = req.headers["group_id"] as string;
|
||||||
const _uploadedBy = req.headers["uploaded_by"] as string;
|
const _uploadedBy = req.headers["uploaded_by"] as string;
|
||||||
const _machineId = req.headers["machine_id"];
|
const _machineId = req.headers["machine_id"];
|
||||||
const _isDocumentation = req.headers["is_documentation"] as string;
|
const _isDocumentation = req.headers["is_documentation"] as string;
|
||||||
const _isRestricted = req.headers["is_restricted"] as string;
|
const _isRestricted = req.headers["is_restricted"] as string;
|
||||||
const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean);
|
const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean);
|
||||||
console.log(
|
console.log(
|
||||||
_fileName,
|
_fileName,
|
||||||
_groupId,
|
_groupId,
|
||||||
_uploadedBy,
|
_uploadedBy,
|
||||||
_machineId,
|
_machineId,
|
||||||
_isDocumentation,
|
_isDocumentation,
|
||||||
_isRestricted,
|
_isRestricted,
|
||||||
_isAdmin,
|
_isAdmin,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Vérifier que les en-têtes nécessaires sont présents
|
// Vérifier que les en-têtes nécessaires sont présents
|
||||||
if (!_fileName || !_machineId) {
|
if (!_fileName || !_machineId) {
|
||||||
throw new BadRequestException("Header(s) manquant(s)");
|
throw new BadRequestException("Header(s) manquant(s)");
|
||||||
}
|
}
|
||||||
console.log("Header found !");
|
console.log("Header found !");
|
||||||
const machineId = Array(_machineId);
|
const machineId = Array(_machineId);
|
||||||
|
|
||||||
const Params = new Map()
|
const Params = new Map()
|
||||||
.set("fileName", _fileName.toString())
|
.set("fileName", _fileName.toString())
|
||||||
.set("groupId", _groupId.toString() || null)
|
.set("groupId", _groupId.toString() || null)
|
||||||
.set("uploadedBy", _uploadedBy.toString())
|
.set("uploadedBy", _uploadedBy.toString())
|
||||||
.set("machineId", Array(JSON.parse(machineId.toString())))
|
.set("machineId", Array(JSON.parse(machineId.toString())))
|
||||||
.set("isDocumentation", false)
|
.set("isDocumentation", false)
|
||||||
.set("isRestricted", false);
|
.set("isRestricted", false);
|
||||||
|
|
||||||
console.log("Current params :\n", Params);
|
console.log("Current params :\n", Params);
|
||||||
|
|
||||||
//TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters.
|
//TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters.
|
||||||
if (_isAdmin) {
|
if (_isAdmin) {
|
||||||
Params.set("isDocumentation", Boolean(_isDocumentation));
|
Params.set("isDocumentation", Boolean(_isDocumentation));
|
||||||
Params.set("isRestricted", Boolean(_isRestricted));
|
Params.set("isRestricted", Boolean(_isRestricted));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Executing save procedure...");
|
console.log("Executing save procedure...");
|
||||||
return (
|
return (
|
||||||
res
|
res
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.status(HttpStatus.CREATED)
|
.status(HttpStatus.CREATED)
|
||||||
.send(await this.filesService.save(fileBuffer, Params))
|
.send(await this.filesService.save(fileBuffer, Params))
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return (
|
return (
|
||||||
res
|
res
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
.send(err)
|
.send(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
req.on("error", (err) => {
|
req.on("error", (err) => {
|
||||||
return (
|
return (
|
||||||
res
|
res
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
.send(err)
|
.send(err)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.FOUND)
|
@HttpCode(HttpStatus.FOUND)
|
||||||
@Get("find")
|
@Get("find")
|
||||||
async findMany(
|
async findMany(
|
||||||
@Query("limit", new DefaultValuePipe(20), ParseIntPipe) limit: number,
|
@Query("limit", new DefaultValuePipe(20), ParseIntPipe) limit: number,
|
||||||
@Query("offset", new DefaultValuePipe(0), ParseIntPipe) offset: number,
|
@Query("offset", new DefaultValuePipe(0), ParseIntPipe) offset: number,
|
||||||
@Query("search", new DefaultValuePipe("")) search: string,
|
@Query("search", new DefaultValuePipe("")) search: string,
|
||||||
) {
|
) {
|
||||||
return this.filesService.search(limit, offset, search);
|
return this.filesService.search(limit, offset, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.FOUND)
|
@HttpCode(HttpStatus.FOUND)
|
||||||
@Get(":fileId")
|
@Get("types")
|
||||||
async getFile(@Param("fileId") fileId: string) {
|
async getTypes() {
|
||||||
return await this.filesService.get(fileId);
|
console.log("Performing request")
|
||||||
}
|
return await this.filesService.getAllFilesTypes();
|
||||||
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.CREATED)
|
||||||
@UseGuards(AdminGuard)
|
@UseGuards(AdminGuard)
|
||||||
@Delete(":fileId")
|
@Post("types/new")
|
||||||
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
|
async newType(@Body() body: CreateFileTypeDto) {
|
||||||
return await this.filesService.deleteFile(fileId);
|
return await this.filesService.createFileType(body.name, body.mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.FOUND)
|
@HttpCode(HttpStatus.ACCEPTED)
|
||||||
@Get("types")
|
@UseGuards(AdminGuard)
|
||||||
async getTypes() {
|
@Delete("types/:typeId")
|
||||||
return await this.filesService.getAllFilesTypes();
|
async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) {
|
||||||
}
|
return await this.filesService.removeFileType(typeId)
|
||||||
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.CREATED)
|
@HttpCode(HttpStatus.FOUND)
|
||||||
@UseGuards(AdminGuard)
|
@Get(":fileId")
|
||||||
@Post("types/new")
|
async getFile(@Param("fileId") fileId: string) {
|
||||||
async newType(@Body() body: CreateFileTypeDto) {
|
return await this.filesService.get(fileId);
|
||||||
return await this.filesService.createFileType(body.name, body.mime);
|
}
|
||||||
}
|
|
||||||
|
@HttpCode(HttpStatus.OK)
|
||||||
|
@UseGuards(AdminGuard)
|
||||||
|
@Delete(":fileId")
|
||||||
|
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
|
||||||
|
return await this.filesService.deleteFile(fileId);
|
||||||
|
}
|
||||||
|
|
||||||
@HttpCode(HttpStatus.ACCEPTED)
|
|
||||||
@UseGuards(AdminGuard)
|
|
||||||
@Delete("types/:typeId")
|
|
||||||
async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,13 @@ export class FilesService {
|
|||||||
}
|
}
|
||||||
if (sameFileInStorage.length === 1) {
|
if (sameFileInStorage.length === 1) {
|
||||||
//if there is one only entry then remove the file from the storage and the database.
|
//if there is one only entry then remove the file from the storage and the database.
|
||||||
|
await this.database
|
||||||
|
.use()
|
||||||
|
.delete(FilesForMachinesTable)
|
||||||
|
.where(eq(FilesForMachinesTable.fileId, fileId))
|
||||||
|
.prepare("deleteFileAssociationFromMachine")
|
||||||
|
.execute();
|
||||||
|
|
||||||
await this.database
|
await this.database
|
||||||
.use()
|
.use()
|
||||||
.delete(FilesTable)
|
.delete(FilesTable)
|
||||||
@@ -286,12 +293,14 @@ export class FilesService {
|
|||||||
* @return {Promise<Array>} Promise that resolves to an array of file types.
|
* @return {Promise<Array>} Promise that resolves to an array of file types.
|
||||||
*/
|
*/
|
||||||
public async getAllFilesTypes(): Promise<Array<object>> {
|
public async getAllFilesTypes(): Promise<Array<object>> {
|
||||||
return await this.database
|
const result = await this.database
|
||||||
.use()
|
.use()
|
||||||
.select()
|
.select()
|
||||||
.from(FilesTypesTable)
|
.from(FilesTypesTable)
|
||||||
.prepare("getAllFilesTypes")
|
.prepare("getAllFilesTypes")
|
||||||
.execute();
|
.execute();
|
||||||
|
console.log(result)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
/**
|
|
||||||
* This is not a production server yet!
|
|
||||||
* This is only a minimal backend to get started.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Logger } from "@nestjs/common";
|
import { Logger } from "@nestjs/common";
|
||||||
import { NestFactory } from "@nestjs/core";
|
import { NestFactory } from "@nestjs/core";
|
||||||
|
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
|
||||||
import helmet from "helmet";
|
import helmet from "helmet";
|
||||||
import { AppModule } from "./app/app.module";
|
import { AppModule } from "./app/app.module";
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
|
|
||||||
|
const config = new DocumentBuilder()
|
||||||
|
.setTitle('Fab Explorer')
|
||||||
|
.setDescription("Définition de l'api du FabLab Explorer")
|
||||||
|
.setVersion('1.0')
|
||||||
|
.build();
|
||||||
|
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
const globalPrefix = "api";
|
const globalPrefix = "api";
|
||||||
app.setGlobalPrefix(globalPrefix);
|
app.setGlobalPrefix(globalPrefix);
|
||||||
app.use(helmet());
|
app.use(helmet());
|
||||||
const port = process.env.PORT || 3000;
|
const port = process.env.PORT || 3000;
|
||||||
|
|
||||||
|
const document = SwaggerModule.createDocument(app, config);
|
||||||
|
SwaggerModule.setup('api', app, document);
|
||||||
|
|
||||||
await app.listen(port);
|
await app.listen(port);
|
||||||
Logger.log(
|
Logger.log(
|
||||||
`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`,
|
`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"@nestjs/core": "^10.4.4",
|
"@nestjs/core": "^10.4.4",
|
||||||
"@nestjs/mapped-types": "*",
|
"@nestjs/mapped-types": "*",
|
||||||
"@nestjs/platform-express": "^10.4.4",
|
"@nestjs/platform-express": "^10.4.4",
|
||||||
|
"@nestjs/swagger": "^7.4.2",
|
||||||
"@nestjs/throttler": "^6.2.1",
|
"@nestjs/throttler": "^6.2.1",
|
||||||
"@radix-ui/react-accordion": "^1.2.1",
|
"@radix-ui/react-accordion": "^1.2.1",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.2",
|
"@radix-ui/react-alert-dialog": "^1.1.2",
|
||||||
|
|||||||
45
pnpm-lock.yaml
generated
45
pnpm-lock.yaml
generated
@@ -26,6 +26,9 @@ importers:
|
|||||||
'@nestjs/platform-express':
|
'@nestjs/platform-express':
|
||||||
specifier: ^10.4.4
|
specifier: ^10.4.4
|
||||||
version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4)
|
version: 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4)
|
||||||
|
'@nestjs/swagger':
|
||||||
|
specifier: ^7.4.2
|
||||||
|
version: 7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)
|
||||||
'@nestjs/throttler':
|
'@nestjs/throttler':
|
||||||
specifier: ^6.2.1
|
specifier: ^6.2.1
|
||||||
version: 6.2.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)
|
version: 6.2.1(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(reflect-metadata@0.1.14)
|
||||||
@@ -1582,6 +1585,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
|
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
'@microsoft/tsdoc@0.15.0':
|
||||||
|
resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==}
|
||||||
|
|
||||||
'@module-federation/bridge-react-webpack-plugin@0.2.8':
|
'@module-federation/bridge-react-webpack-plugin@0.2.8':
|
||||||
resolution: {integrity: sha512-6G1qTo1HWvRcN5fzE+SZgvgzSPoq5YqNx8hFL8BttJmnd3wj4SUOFiikAsXhdVrzSK+Zuzg6pipkiLH1m+pbtw==}
|
resolution: {integrity: sha512-6G1qTo1HWvRcN5fzE+SZgvgzSPoq5YqNx8hFL8BttJmnd3wj4SUOFiikAsXhdVrzSK+Zuzg6pipkiLH1m+pbtw==}
|
||||||
|
|
||||||
@@ -1712,6 +1718,23 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.3.5'
|
typescript: '>=4.3.5'
|
||||||
|
|
||||||
|
'@nestjs/swagger@7.4.2':
|
||||||
|
resolution: {integrity: sha512-Mu6TEn1M/owIvAx2B4DUQObQXqo2028R2s9rSZ/hJEgBK95+doTwS0DjmVA2wTeZTyVtXOoN7CsoM5pONBzvKQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@fastify/static': ^6.0.0 || ^7.0.0
|
||||||
|
'@nestjs/common': ^9.0.0 || ^10.0.0
|
||||||
|
'@nestjs/core': ^9.0.0 || ^10.0.0
|
||||||
|
class-transformer: '*'
|
||||||
|
class-validator: '*'
|
||||||
|
reflect-metadata: ^0.1.12 || ^0.2.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@fastify/static':
|
||||||
|
optional: true
|
||||||
|
class-transformer:
|
||||||
|
optional: true
|
||||||
|
class-validator:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@nestjs/testing@10.4.4':
|
'@nestjs/testing@10.4.4':
|
||||||
resolution: {integrity: sha512-qRGFj51A5RM7JqA8pcyEwSLA3Y0dle/PAZ8oxP0suimoCusRY3Tk7wYqutZdCNj1ATb678SDaUZDHk2pwSv9/g==}
|
resolution: {integrity: sha512-qRGFj51A5RM7JqA8pcyEwSLA3Y0dle/PAZ8oxP0suimoCusRY3Tk7wYqutZdCNj1ATb678SDaUZDHk2pwSv9/g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -7894,6 +7917,9 @@ packages:
|
|||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
swagger-ui-dist@5.17.14:
|
||||||
|
resolution: {integrity: sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==}
|
||||||
|
|
||||||
symbol-tree@3.2.4:
|
symbol-tree@3.2.4:
|
||||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||||
|
|
||||||
@@ -9971,6 +9997,8 @@ snapshots:
|
|||||||
|
|
||||||
'@lukeed/csprng@1.1.0': {}
|
'@lukeed/csprng@1.1.0': {}
|
||||||
|
|
||||||
|
'@microsoft/tsdoc@0.15.0': {}
|
||||||
|
|
||||||
'@module-federation/bridge-react-webpack-plugin@0.2.8':
|
'@module-federation/bridge-react-webpack-plugin@0.2.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@module-federation/sdk': 0.2.8
|
'@module-federation/sdk': 0.2.8
|
||||||
@@ -10171,6 +10199,21 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- chokidar
|
- chokidar
|
||||||
|
|
||||||
|
'@nestjs/swagger@7.4.2(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)':
|
||||||
|
dependencies:
|
||||||
|
'@microsoft/tsdoc': 0.15.0
|
||||||
|
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
|
||||||
|
'@nestjs/core': 10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1)
|
||||||
|
'@nestjs/mapped-types': 2.0.5(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)
|
||||||
|
js-yaml: 4.1.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
path-to-regexp: 3.3.0
|
||||||
|
reflect-metadata: 0.1.14
|
||||||
|
swagger-ui-dist: 5.17.14
|
||||||
|
optionalDependencies:
|
||||||
|
class-transformer: 0.5.1
|
||||||
|
class-validator: 0.14.1
|
||||||
|
|
||||||
'@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4))':
|
'@nestjs/testing@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/platform-express@10.4.4(@nestjs/common@10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1))(@nestjs/core@10.4.4))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
|
'@nestjs/common': 10.4.4(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1)
|
||||||
@@ -17863,6 +17906,8 @@ snapshots:
|
|||||||
csso: 5.0.5
|
csso: 5.0.5
|
||||||
picocolors: 1.0.1
|
picocolors: 1.0.1
|
||||||
|
|
||||||
|
swagger-ui-dist@5.17.14: {}
|
||||||
|
|
||||||
symbol-tree@3.2.4: {}
|
symbol-tree@3.2.4: {}
|
||||||
|
|
||||||
tailwind-merge@2.5.3: {}
|
tailwind-merge@2.5.3: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user