Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NEXT_PUBLIC_API_TOKEN=""
JWT_SECRET=""
NODE_ENV=""
NODE_ENV=""
NEXT_PUBLIC_API_URL=""
2 changes: 1 addition & 1 deletion backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function main() {
const imageId = req.params.id;
const filename = captchaImageMap[imageId];
if (filename) {
const imagePath = path.join(__dirname, 'images', filename);
const imagePath = path.join(__dirname, 'images/captcha', filename);
res.sendFile(imagePath);
} else {
res.status(404).send('Image not found');
Expand Down
2 changes: 1 addition & 1 deletion backend/src/resolvers/captcha.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class CaptchaResolver {

const id = uuidv4();

const imagesDir = path.join(__dirname, '..', 'images');
const imagesDir = path.join(__dirname, '..', 'images/captcha');

const files = fs.readdirSync(imagesDir);

Expand Down
1 change: 0 additions & 1 deletion backend/tests/routes/badge-project.test-not.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import request from 'supertest';
import express from 'express';
import { PrismaClient } from '@prisma/client';
import { Request, Response } from 'express';
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
context: ./frontend
args:
NEXT_PUBLIC_API_TOKEN: ${NEXT_PUBLIC_API_TOKEN}
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
ports:
- 3000:3000
volumes:
Expand All @@ -30,6 +31,7 @@ services:
- WATCHPACK_POLLING=true
- NEXT_PUBLIC_IMAGE_URL=http://localhost:8000
- NEXT_PUBLIC_API_TOKEN=${NEXT_PUBLIC_API_TOKEN}
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
- API_URL=${API_URL}
- NODE_ENV=development
env_file:
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/Captcha/Captcha.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const CaptchaModal: React.FC<Props> = ({
const imageUrls = response.data.generateCaptcha.images.map(
(img) => img.url
);
console.log("imageUrls", imageUrls)
preloadImages(imageUrls).then(() => {
setImages(response.data.generateCaptcha.images);
setChallengeType(response.data.generateCaptcha.challengeType);
Expand All @@ -108,6 +109,7 @@ const CaptchaModal: React.FC<Props> = ({
}
})
.catch((error) => {
console.log("error", error);
showAlert("error", getErrorMessage(error));
setLoading(false);
setCheckRefresh(false);
Expand All @@ -127,6 +129,7 @@ const CaptchaModal: React.FC<Props> = ({
generateCaptcha
.refetch()
.then((response) => {
console.log(response)
if (response.data) {
const imageUrls = response.data.generateCaptcha.images.map(
(img) => img.url
Expand Down
179 changes: 175 additions & 4 deletions frontend/src/types/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,29 @@ export type Scalars = {
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
DateTimeISO: { input: any; output: any; }
};

export type BackupFileInfo = {
__typename?: 'BackupFileInfo';
createdAt: Scalars['DateTimeISO']['output'];
fileName: Scalars['String']['output'];
modifiedAt: Scalars['DateTimeISO']['output'];
sizeBytes: Scalars['Int']['output'];
};

export type BackupFilesResponse = {
__typename?: 'BackupFilesResponse';
code: Scalars['Int']['output'];
files?: Maybe<Array<BackupFileInfo>>;
message: Scalars['String']['output'];
};

export type BackupResponse = {
__typename?: 'BackupResponse';
code: Scalars['Int']['output'];
message: Scalars['String']['output'];
path: Scalars['String']['output'];
};

export type CaptchaImage = {
Expand Down Expand Up @@ -75,6 +98,21 @@ export type CreateEducationInput = {
year: Scalars['Int']['input'];
};

export type CreateExperienceInput = {
business: Scalars['String']['input'];
employmentContractEN: Scalars['String']['input'];
employmentContractFR: Scalars['String']['input'];
endDateEN: Scalars['String']['input'];
endDateFR: Scalars['String']['input'];
jobEN: Scalars['String']['input'];
jobFR: Scalars['String']['input'];
month: Scalars['Float']['input'];
startDateEN: Scalars['String']['input'];
startDateFR: Scalars['String']['input'];
typeEN: Scalars['String']['input'];
typeFR: Scalars['String']['input'];
};

export type CreateProjectInput = {
contentDisplay: Scalars['String']['input'];
descriptionEN: Scalars['String']['input'];
Expand All @@ -91,6 +129,13 @@ export type CreateSkillInput = {
name: Scalars['String']['input'];
};

export type CreateUserInput = {
email: Scalars['String']['input'];
firstname: Scalars['String']['input'];
lastname: Scalars['String']['input'];
role: Scalars['String']['input'];
};

export type Education = {
__typename?: 'Education';
diplomaLevelEN: Scalars['String']['output'];
Expand Down Expand Up @@ -127,14 +172,14 @@ export type EducationsResponse = {
export type Experience = {
__typename?: 'Experience';
business: Scalars['String']['output'];
employmentContractEN?: Maybe<Scalars['String']['output']>;
employmentContractFR?: Maybe<Scalars['String']['output']>;
employmentContractEN: Scalars['String']['output'];
employmentContractFR: Scalars['String']['output'];
endDateEN: Scalars['String']['output'];
endDateFR: Scalars['String']['output'];
id: Scalars['ID']['output'];
jobEN: Scalars['String']['output'];
jobFR: Scalars['String']['output'];
month?: Maybe<Scalars['Int']['output']>;
month: Scalars['Float']['output'];
startDateEN: Scalars['String']['output'];
startDateFR: Scalars['String']['output'];
typeEN: Scalars['String']['output'];
Expand All @@ -155,6 +200,37 @@ export type ExperiencesResponse = {
message: Scalars['String']['output'];
};

export type GlobalStats = {
__typename?: 'GlobalStats';
totalEducations: Scalars['Int']['output'];
totalExperiences: Scalars['Int']['output'];
totalProjects: Scalars['Int']['output'];
totalSkills: Scalars['Int']['output'];
totalUsers: Scalars['Int']['output'];
usersByRoleAdmin: Scalars['Int']['output'];
usersByRoleEditor: Scalars['Int']['output'];
usersByRoleView: Scalars['Int']['output'];
};

export type GlobalStatsResponse = {
__typename?: 'GlobalStatsResponse';
code: Scalars['Int']['output'];
message: Scalars['String']['output'];
stats?: Maybe<GlobalStats>;
};

export type LoginInput = {
email: Scalars['String']['input'];
password: Scalars['String']['input'];
};

export type LoginResponse = {
__typename?: 'LoginResponse';
code: Scalars['Int']['output'];
message: Scalars['String']['output'];
token?: Maybe<Scalars['String']['output']>;
};

export type MessageType = {
__typename?: 'MessageType';
label: Scalars['String']['output'];
Expand All @@ -164,24 +240,39 @@ export type MessageType = {

export type Mutation = {
__typename?: 'Mutation';
changePassword: Response;
clearCaptcha: Scalars['Boolean']['output'];
createCategory: CategoryResponse;
createEducation: EducationResponse;
createExperience: ExperienceResponse;
createProject: ProjectResponse;
createSkill: SubItemResponse;
deleteBackupFile: Response;
deleteCategory: CategoryResponse;
deleteEducation: EducationResponse;
deleteExperience: ExperienceResponse;
deleteProject: Response;
deleteSkill: SubItemResponse;
generateDatabaseBackup: BackupResponse;
login: LoginResponse;
logout: Response;
registerUser: UserResponse;
sendContact: MessageType;
updateCategory: CategoryResponse;
updateEducation: EducationResponse;
updateExperience: ExperienceResponse;
updateProject: ProjectResponse;
updateSkill: SubItemResponse;
validateCaptcha: ValidationResponse;
};


export type MutationChangePasswordArgs = {
email: Scalars['String']['input'];
newPassword: Scalars['String']['input'];
};


export type MutationClearCaptchaArgs = {
idCaptcha: Scalars['String']['input'];
};
Expand All @@ -197,6 +288,11 @@ export type MutationCreateEducationArgs = {
};


export type MutationCreateExperienceArgs = {
data: CreateExperienceInput;
};


export type MutationCreateProjectArgs = {
data: CreateProjectInput;
};
Expand All @@ -207,6 +303,11 @@ export type MutationCreateSkillArgs = {
};


export type MutationDeleteBackupFileArgs = {
fileName: Scalars['String']['input'];
};


export type MutationDeleteCategoryArgs = {
id: Scalars['Int']['input'];
};
Expand All @@ -217,6 +318,11 @@ export type MutationDeleteEducationArgs = {
};


export type MutationDeleteExperienceArgs = {
id: Scalars['Int']['input'];
};


export type MutationDeleteProjectArgs = {
id: Scalars['Int']['input'];
};
Expand All @@ -227,6 +333,16 @@ export type MutationDeleteSkillArgs = {
};


export type MutationLoginArgs = {
data: LoginInput;
};


export type MutationRegisterUserArgs = {
data: CreateUserInput;
};


export type MutationSendContactArgs = {
data: ContactFrom;
};
Expand All @@ -243,6 +359,11 @@ export type MutationUpdateEducationArgs = {
};


export type MutationUpdateExperienceArgs = {
data: UpdateExperienceInput;
};


export type MutationUpdateProjectArgs = {
data: UpdateProjectInput;
};
Expand Down Expand Up @@ -293,9 +414,12 @@ export type Query = {
experienceById: ExperienceResponse;
experienceList: ExperiencesResponse;
generateCaptcha: CaptchaResponse;
getGlobalStats: GlobalStatsResponse;
listBackupFiles: BackupFilesResponse;
projectById: ProjectResponse;
projectList: ProjectsResponse;
skillList: CategoryResponse;
userList: UsersResponse;
};


Expand All @@ -319,6 +443,13 @@ export type Response = {
message: Scalars['String']['output'];
};

/** User roles */
export enum Role {
Admin = 'admin',
Editor = 'editor',
View = 'view'
}

export type Skill = {
__typename?: 'Skill';
categoryEN: Scalars['String']['output'];
Expand Down Expand Up @@ -365,6 +496,22 @@ export type UpdateEducationInput = {
year?: InputMaybe<Scalars['Int']['input']>;
};

export type UpdateExperienceInput = {
business?: InputMaybe<Scalars['String']['input']>;
employmentContractEN?: InputMaybe<Scalars['String']['input']>;
employmentContractFR?: InputMaybe<Scalars['String']['input']>;
endDateEN?: InputMaybe<Scalars['String']['input']>;
endDateFR?: InputMaybe<Scalars['String']['input']>;
id: Scalars['Int']['input'];
jobEN?: InputMaybe<Scalars['String']['input']>;
jobFR?: InputMaybe<Scalars['String']['input']>;
month?: InputMaybe<Scalars['Float']['input']>;
startDateEN?: InputMaybe<Scalars['String']['input']>;
startDateFR?: InputMaybe<Scalars['String']['input']>;
typeEN?: InputMaybe<Scalars['String']['input']>;
typeFR?: InputMaybe<Scalars['String']['input']>;
};

export type UpdateProjectInput = {
contentDisplay?: InputMaybe<Scalars['String']['input']>;
descriptionEN?: InputMaybe<Scalars['String']['input']>;
Expand All @@ -382,6 +529,30 @@ export type UpdateSkillInput = {
name?: InputMaybe<Scalars['String']['input']>;
};

export type User = {
__typename?: 'User';
email: Scalars['String']['output'];
firstname: Scalars['String']['output'];
id: Scalars['ID']['output'];
isPasswordChange: Scalars['Boolean']['output'];
lastname: Scalars['String']['output'];
role: Role;
};

export type UserResponse = {
__typename?: 'UserResponse';
code: Scalars['Int']['output'];
message: Scalars['String']['output'];
user?: Maybe<User>;
};

export type UsersResponse = {
__typename?: 'UsersResponse';
code: Scalars['Int']['output'];
message: Scalars['String']['output'];
users?: Maybe<Array<User>>;
};

export type ValidationResponse = {
__typename?: 'ValidationResponse';
isValid: Scalars['Boolean']['output'];
Expand Down Expand Up @@ -423,7 +594,7 @@ export type GetEducationsListQuery = { __typename?: 'Query', educationList: { __
export type GetExperiencesListQueryVariables = Exact<{ [key: string]: never; }>;


export type GetExperiencesListQuery = { __typename?: 'Query', experienceList: { __typename?: 'ExperiencesResponse', message: string, code: number, experiences?: Array<{ __typename?: 'Experience', employmentContractEN?: string | null, business: string, employmentContractFR?: string | null, endDateEN: string, endDateFR: string, jobEN: string, id: string, jobFR: string, month?: number | null, startDateEN: string, startDateFR: string, typeEN: string, typeFR: string }> | null } };
export type GetExperiencesListQuery = { __typename?: 'Query', experienceList: { __typename?: 'ExperiencesResponse', message: string, code: number, experiences?: Array<{ __typename?: 'Experience', employmentContractEN: string, business: string, employmentContractFR: string, endDateEN: string, endDateFR: string, jobEN: string, id: string, jobFR: string, month: number, startDateEN: string, startDateFR: string, typeEN: string, typeFR: string }> | null } };

export type GetProjectsListQueryVariables = Exact<{ [key: string]: never; }>;

Expand Down