Skip to content

Commit

Permalink
Merge pull request #91 from WildCodeSchool/22_download_part2
Browse files Browse the repository at this point in the history
22 download part2
  • Loading branch information
MaximeG971 authored Nov 8, 2024
2 parents a48e718 + 2c22024 commit e6598c2
Show file tree
Hide file tree
Showing 15 changed files with 1,519 additions and 351 deletions.
4 changes: 2 additions & 2 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
FROM node:lts-alpine
FROM node:lts-alpine3.18

WORKDIR /app

RUN apk --no-cache add curl

COPY package.json package.json
RUN npm install
RUN npm install loglevel --verbose

COPY tsconfig.json tsconfig.json

Expand Down
58 changes: 34 additions & 24 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import "reflect-metadata";
import {buildSchema} from "type-graphql";
import {ApolloServer} from "@apollo/server";
import {ApolloServerPluginDrainHttpServer} from '@apollo/server/plugin/drainHttpServer';
import { buildSchema } from "type-graphql";
import { ApolloServer } from "@apollo/server";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import express from "express";
import http from "http";
import cors from "cors";
import jwt from "jsonwebtoken";
import {dataSource} from "./config/db";
import { dataSource } from "./config/db";
import PlanResolver from "./resolvers/PlanResolver";
import ReportResolver from "./resolvers/ReportResolver";
import UploadResolver from "./resolvers/UploadResolver";
Expand All @@ -15,20 +15,19 @@ import UserResolver from "./resolvers/UserResolver";
import FileResolver from "./resolvers/FileResolver";
import UserAccessFileResolver from "./resolvers/UserAccessFileResolver";
import BillingResolver from "./resolvers/BillingResolver";
import {startStandaloneServer} from "@apollo/server/standalone";
import cookie from 'cookie'
import { startStandaloneServer } from "@apollo/server/standalone";
import cookie from "cookie";
import path from "path";
import dotenv from 'dotenv'
import dotenv from "dotenv";

dotenv.config({path: path.join(__dirname, '../../.env')})
dotenv.config({ path: path.join(__dirname, "../../.env") });

export type Context = {
id: number;
email: string;
role: string;
};


const start = async () => {
await dataSource.initialize();

Expand All @@ -44,8 +43,7 @@ const start = async () => {
BillingResolver,
],


authChecker: ({context}: { context: Context }, roles) => {
authChecker: ({ context }: { context: Context }, roles) => {
console.log("roles for this query/mutation ", roles);
// Check user
if (!context.email) {
Expand All @@ -71,21 +69,33 @@ const start = async () => {
const app = express();
const httpServer = http.createServer(app);

app.use(cors({
origin: ["http://localhost:7002", "http://localhost:3000", "http://localhost:5173"],
credentials: true,
methods: ["POST", "GET", "DELETE", "PUT", "OPTIONS"],
allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"]
}));
app.use(
cors({
origin: [
"http://localhost:7002",
"http://localhost:3000",
"http://localhost:5173",
],
credentials: true,
methods: ["POST", "GET", "DELETE", "PUT", "OPTIONS"],
allowedHeaders: [
"Origin",
"X-Requested-With",
"Content-Type",
"Accept",
"Authorization",
],
})
);

const server = new ApolloServer({
schema,
plugins: [ApolloServerPluginDrainHttpServer({httpServer})],
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});

const {url} = await startStandaloneServer(server, {
listen: {port: 4000},
context: async ({req, res}) => {
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
context: async ({ req, res }) => {
if (process.env.JWT_SECRET_KEY === undefined) {
throw new Error("NO JWT SECRET KEY CONFIGURED");
}
Expand All @@ -98,12 +108,12 @@ const start = async () => {
) as jwt.JwtPayload;

if (payload) {
return {...payload, res: res};
return { ...payload, res: res };
}
}
return {res: res};
return { res: res };
},
})
});

console.log(`🚀 Server ready at ${url}`);
};
Expand Down
63 changes: 59 additions & 4 deletions backend/src/resolvers/UploadResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { Arg, Mutation, Query, Resolver } from "type-graphql";
import { Visitor } from "../entities/visitor";
import { User } from "../entities/user";
import { File } from "../entities/file";
import { createDownloadToken, generateDownloadLink } from "../helpers/linkGenerator";
import {
createDownloadToken,
generateDownloadLink,
} from "../helpers/linkGenerator";
import jwt from "jsonwebtoken";

@Resolver(Upload)
class UploadResolver {
Expand Down Expand Up @@ -44,7 +48,9 @@ class UploadResolver {

try {
await upload.save();
return `Upload ${upload.is_activated ? "activated" : "deactivated"}`;
return `Upload ${
upload.is_activated ? "activated" : "deactivated"
}`;
} catch (err) {
throw new Error("Internal server error");
}
Expand Down Expand Up @@ -103,7 +109,8 @@ class UploadResolver {
"1h"
);

const downloadLink: string = generateDownloadLink(downloadToken);
const downloadLink: string =
generateDownloadLink(downloadToken);

return downloadLink;
}
Expand All @@ -113,6 +120,54 @@ class UploadResolver {
throw new Error("Internal server error");
}
}

@Mutation(() => [File])
async getFilesFromUpload(
@Arg("token", () => String) token: string
): Promise<File[]> {
// Décoder le token pour récupérer upload id
// Initie fonction pour chercher les files en relation avec cet upload
// Envoyer les files

try {
if (!process.env.JWT_SECRET_KEY) {
throw new Error(
"JWT_SECRET_KEY is not defined in environment variables"
);
}

const payload = jwt.verify(
token,
process.env.JWT_SECRET_KEY as string
) as jwt.JwtPayload;

const uploadId = payload.uploadId;
if (!uploadId) {
throw new Error("Invalid token: uploadId not found");
}
console.log(uploadId);

const upload = await Upload.findOne({
where: { id: uploadId },
relations: ["files"],
});

if (!upload || !upload.files) {
throw new Error("No files found for this upload");
}
console.log(uploadId);

return upload.files;
} catch (err: unknown) {
console.error("Error retrieving files from upload:", err);

if (err instanceof Error) {
throw new Error("Invalid or expired token: " + err.message);
}

throw new Error("An unknown error occurred");
}
}
}

const userOrVisitor = async (email: string): Promise<User | Visitor> => {
Expand All @@ -127,4 +182,4 @@ const userOrVisitor = async (email: string): Promise<User | Visitor> => {
return visitor;
};

export default UploadResolver;
export default UploadResolver;
134 changes: 67 additions & 67 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
services:
backend:
build: ./backend
volumes:
- ./backend/src:/app/src
env_file:
- .env
healthcheck:
test: 'curl --fail --request POST --header ''content-type: application/json'' --url ''http://localhost:4000/graphql'' --data ''{"query":"query { __typename }"}'' || exit 1'
interval: 1s
timeout: 2s
retries: 100
depends_on:
db:
condition: service_healthy
frontend:
build: ./frontend
volumes:
- ./frontend/src:/app/src
depends_on:
backend:
condition: service_healthy
env_file:
- .env
healthcheck:
test: "curl --fail --request GET --url 'http://localhost:5173' || exit 1"
interval: 1s
timeout: 2s
retries: 100
db:
image: postgres
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d postgres -U postgres" ]
interval: 1s
timeout: 2s
retries: 100
environment:
POSTGRES_PASSWORD: postgres
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
- ./postgres-data/data:/var/lib/postgresql/data
adminer:
image: adminer
ports:
- 8080:8080
files:
build: ./files
healthcheck:
test: "curl --fail --request GET --url 'http://localhost:3000' || exit 1"
interval: 1s
timeout: 2s
env_file:
- .env
volumes:
- ./files/src:/app/src
apigateway:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_healthy
files:
condition: service_healthy
ports:
- "7002:80"
backend:
build: ./backend
volumes:
- ./backend/src:/app/src
env_file:
- .env
healthcheck:
test: 'curl --fail --request POST --header ''content-type: application/json'' --url ''http://localhost:4000/graphql'' --data ''{"query":"query { __typename }"}'' || exit 1'
interval: 1s
timeout: 2s
retries: 100
depends_on:
db:
condition: service_healthy
frontend:
build: ./frontend
volumes:
- ./frontend/src:/app/src
depends_on:
backend:
condition: service_healthy
env_file:
- .env
healthcheck:
test: "curl --fail --request GET --url 'http://localhost:5173' || exit 1"
interval: 1s
timeout: 2s
retries: 100
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -d postgres -U postgres"]
interval: 1s
timeout: 2s
retries: 100
environment:
POSTGRES_PASSWORD: postgres
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
- ./postgres-data/data:/var/lib/postgresql/data
adminer:
image: adminer
ports:
- 8080:8080
files:
build: ./files
healthcheck:
test: "curl --fail --request GET --url 'http://localhost:3000' || exit 1"
interval: 1s
timeout: 2s
env_file:
- .env
volumes:
- ./files/src:/app/src
apigateway:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_healthy
files:
condition: service_healthy
ports:
- "7002:80"
4 changes: 2 additions & 2 deletions files/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:lts-alpine
FROM node:lts-alpine3.18

RUN apk --no-cache add curl

Expand All @@ -8,7 +8,7 @@ RUN mkdir UPLOADS_DIR
COPY tsconfig.json tsconfig.json

COPY package.json package.json
RUN npm i
RUN npm install loglevel --verbose

COPY src src

Expand Down
Loading

0 comments on commit e6598c2

Please sign in to comment.